Das Selbständern des Codes

In der Informatik, Code selbstmodifizierend, ist Code, der seine eigenen Instruktionen verändert, während es - gewöhnlich durchführt, um die Instruktionspfad-Länge zu reduzieren und Leistung zu verbessern oder einfach sonst wiederholend ähnlichen Code zu reduzieren, so Wartung vereinfachend. Selbst ist Modifizierung eine Alternative zur Methode der 'Fahne-Einstellung' und des bedingten Programm-Ausbreitens, verwendet in erster Linie, um die Anzahl von Zeiten zu vermindern, für die eine Bedingung geprüft werden muss. Der Begriff wird gewöhnlich nur angewandt, um zu codieren, wo die Selbstmodifizierung absichtlich ist, nicht in Situationen, wo Code zufällig sich wegen eines Fehlers wie eine Pufferüberschwemmung modifiziert.

Die Methode wird oft verwendet, um Code des Tests/Beseitigens bedingt anzurufen, ohne zusätzlich rechenbetont oben für jeden Zyklus des Eingangs/Produktion zu verlangen.

Die Modifizierungen können performed: - sein

  • nur während der Initialisierung - gestützt auf Eingangsrahmen (wenn der Prozess als Software 'Konfiguration' allgemeiner beschrieben wird und, in Hardware-Begriffen, zu untergehenden Springern für gedruckte Leiterplatten etwas analog ist). Die Modifizierung von Programm-Zugang-Zeigestöcken ist eine gleichwertige indirekte Methode der Selbstmodifizierung, aber des Verlangens der Koexistenz von einem oder mehr alternativen Instruktionspfaden, die Programm-Größe vergrößernd.
  • während der Ausführung ('während der Übertragung') - gestützt auf besonderen Programm-Staaten, die während der Ausführung erreicht worden sind

In jedem Fall können die Modifizierungen direkt für die Maschinencodeinstruktionen selbst, durch das Überziehen neuer Instruktionen über die vorhandenen durchgeführt werden (zum Beispiel: das Ändern eines Vergleichens und Zweigs zu einem vorbehaltlosen Zweig oder wechselweise einem 'NOP'). In IBM/360 und Z/Architecture Befehlssatz überzieht ein DURCHFÜHREN (AB) die Instruktion seine Zielinstruktion (in seinem 2. Byte) mit der niedrigsten Ordnung 8 Bit des Registers 1, als eine normale, legitime Methode (der vorläufigen) Instruktionsmodifizierung.

Anwendung in der niedrigen Stufe und den hohen Sprachen

Selbstmodifizierung kann in einer Vielfalt von Wegen abhängig von Programmiersprache und seiner Unterstützung für Zeigestöcke und/oder Zugang zum dynamischen Bearbeiter oder Dolmetscher 'Motoren' vollbracht werden: -

  • Bedeckung von vorhandenen Instruktionen (oder Teile von Instruktionen wie opcode, Register, Fahnen oder Adresse) oder
  • direkte Entwicklung von ganzen Instruktionen oder Folgen von Instruktionen im Gedächtnis
  • das Schaffen oder Modifizierung von Quellcodebehauptungen, die von gefolgt sind, 'Mini-kompiliert' oder eine dynamische Interpretation (sieh eval Behauptung)
  • das Schaffen eines kompletten Programms dynamisch und dann die Durchführung davon

Zusammenbau-Sprache

Das Selbständern des Codes ist ziemlich aufrichtig, um durchzuführen, wenn es Zusammenbau-Sprache verwendet. Instruktionen können im Gedächtnis (oder überzogen über den vorhandenen Code in der nichtgeschützten Programm-Lagerung) in einer Folge dynamisch geschaffen werden, die zu denjenigen gleichwertig ist, die ein Standardbearbeiter als der Gegenstand-Code (/binäre Datei) erzeugen kann. Mit modernen Verarbeitern kann es unbeabsichtigte Nebenwirkungen auf dem geheimen Zentraleinheitslager geben, das betrachtet werden muss. Die Methode wurde oft verwendet, um 'das erste Mal' Bedingungen zu prüfen, weil darin angemessen Assemblerbeispiel von IBM/360 kommentiert hat. Es verwendet Instruktionsbedeckung, um die Instruktionspfad-Länge durch (N x 1)-1 zu reduzieren, wo N die Zahl von Aufzeichnungen auf der Datei (-1 ist, die Gemeinkosten seiend, um die Bedeckung durchzuführen).

SUBRTN CLI SUBRTN, X '95' das ERSTE MAL HIER? (diese Instruktion wird während des 1. Males durch sofort überzogen)

BNE HAT sich GEÖFFNET (WIRD DURCH FALLEN, WENN CLI OPCODE, = x '95' UND DOCH NICHT GEÄNDERT WORDEN IST)

MVC SUBRTN (4), SPRUNG JA, ÜBERZIEHEN DEN TEST DURCH DIE BEWEGUNG EINES VORBEHALTLOSEN ZWEIGS (derselbe Länge-Maschinencode)

ÖFFNEN SIE EINGANG und OFFEN DIE EINGANGSDATEI seit seinem ersten Mal bis hier

SPRINGEN SIE B HAT SICH GEÖFFNET DIESE VORBEHALTLOSE 4-BYTE-ZWEIGINSTRUKTION ÜBERZIEHT DIE 4-BYTE-INSTRUKTION AM ETIKETT 'TEST'

GEÖFFNET BEKOMMEN EINGEGEBENE NORMALE IN EINER PROZESSION GEHENDE ZUSAMMENFASSUNGEN HIER

... </Code>

(Da der Ersatz vorbehaltloser Zweig ist auch ein bisschen schneller als eine vergleichen Instruktion, sowie das Reduzieren der gesamten Pfad-Länge, des gesparten Unterschieds im Timing zwischen den zwei Instruktionen, durch einen Faktor von N vergrößert wird. Die 'Sprung'-Instruktion behält Gegend der Verweisung und viel höheren 'Sichtbarkeit' durch seine nächste Nähe zur überschriebenen Instruktion, trotz des Hinzufügens einer unnötigen Extrainstruktion nach dem ÖFFNEN)

In späteren Betriebssystemen für Programme, die in der geschützten Lagerung wohnen, konnte diese Technik nicht verwendet werden, und so würde das Ändern des Zeigestocks zum Unterprogramm stattdessen verwendet. Der Zeigestock würde in der dynamischen Lagerung wohnen und konnte nach Wunsch verändert werden nach dem ersten Pass, um das OFFENE zu umgehen (Die Notwendigkeit habend, einen Zeigestock zuerst statt eines direkten Zweigs & Verbindung zum Unterprogramm zu laden, würde N Instruktionen zur Pfad-Länge hinzufügen - aber würde es die entsprechende Verminderung von N für den vorbehaltlosen Zweig geben, der nicht mehr erforderlich wäre).

Hohe Sprachen

Einige Sprachen erlauben ausführlich, Code zu selbstmodifizieren. Zum Beispiel erlaubt das VERÄNDERN Verb im COBOL Programmen, sich zu modifizieren; eine Gruppe-Programmiertechnik soll Selbständern-Code verwenden. Klipper und SPITBOL stellen auch Möglichkeiten für die ausführliche Selbstmodifizierung zur Verfügung.

Andere Sprachen, wie Perl, Pythonschlange und JavaScript, erlauben Programmen, neuen Code an der Durchlaufzeit zu schaffen und es mit einer Eval-Funktion durchzuführen, aber erlauben vorhandenem Code nicht, verändert zu werden. Das Trugbild der Modifizierung (wenn auch kein Maschinencode wirklich überschrieben wird) wird durch das Ändern von Funktionszeigestöcken, als in diesem Beispiel von JavaScript erreicht:

var f = Funktion (x) {geben x + 1} zurück;

//teilen Sie eine neue Definition zu f zu:

f = neue Funktion ('x', 'x + 2' zurückgeben);

</Quelle>

Lispeln-Makros erlauben auch Laufzeitcodegeneration, ohne eine Schnur grammatisch zu analysieren, die Programm-Code enthält.

Steuertabellen

Wie man

betrachtet werden kann, werden Steuertabelle-Dolmetscher in gewisser Hinsicht durch Datenwerte 'selbstmodifiziert', die aus den Tabelleneinträgen herausgezogen sind (aber nicht spezifisch codiert in bedingten Behauptungen der Form "WENN inputx = 'yyy'" reichen).

Geschichte

IBM SSEC, demonstriert im Januar 1948, ist in der Lage gewesen, seine Instruktionen zu modifizieren oder sonst sie genau wie Daten zu behandeln. Jedoch wurde die Fähigkeit in der Praxis selten verwendet.

In den frühen Tagen von Computern, Code selbstmodifizierend, wurde häufig verwendet, um Gebrauch des beschränkten Gedächtnisses zu reduzieren, oder Leistung oder beide zu verbessern. Es wurde auch manchmal verwendet, um Unterprogramm-Anrufe und Umsatz durchzuführen, als der Befehlssatz nur das einfache Ausbreiten oder Auslassen von Instruktionen zur Verfügung gestellt hat, den Kontrollfluss zu ändern. Dieser Gebrauch ist noch in bestimmten ultra-RISC Architekturen mindestens theoretisch wichtig; sieh zum Beispiel einen Befehlssatz-Computer. Die MISCHUNGS-Architektur von Donald Knuth auch verwendet, Code selbstmodifizierend, um Unterprogramm-Anrufe durchzuführen.

Gebrauch

Das Selbständern des Codes kann zu verschiedenen Zwecken verwendet werden:

  • Halbautomatische Optimierung einer abhängigen Zustandschleife.
  • Laufzeitcodegeneration oder Spezialisierung eines Algorithmus in der Durchlaufzeit oder loadtime (der, zum Beispiel, im Gebiet der Echtzeitgrafik populär ist), wie ein allgemeines Sorte-Dienstprogramm - Vorbereitung des Codes, um den in einer spezifischen Beschwörung beschriebenen Schlüsselvergleich durchzuführen.
  • Das Ändern des inlined Staates eines Gegenstands oder das Simulieren des Aufbaus auf höchster Ebene von Verschlüssen.
  • Flicken des Unterprogramms (Zeigestock) das Adressbenennen, gewöhnlich wie durchgeführt, in der Zeit der Last/Initialisierung von dynamischen Bibliotheken, oder auf jeder Beschwörung, die inneren Verweisungen des Unterprogramms auf seine Rahmen flickend, um wirkliche Adressen von spezifischen Routinen zu verwenden. (d. h. Indirekte 'Selbstmodifizierung').
  • Entwicklungsrechensysteme wie genetische Programmierung.
  • Das Verbergen des Codes, um Rücktechnik (durch den Gebrauch eines Zurückübersetzers oder Testhilfeprogramms) zu verhindern oder Entdeckung durch virus/spyware Abtastung der Software und ähnlich auszuweichen.
  • Die Füllung von 100 % des Gedächtnisses (in einigen Architekturen) mit einem rollenden Muster, opcodes zu wiederholen, alle Programme und Daten zu löschen, oder - in der Hardware zu brennen.
  • Das Zusammendrücken des Codes, der zu dekomprimieren und an der Durchlaufzeit z.B durchzuführen ist, wenn Gedächtnis oder Speicherplatz beschränkt werden.
  • Einige sehr beschränkte Befehlssätze verlassen keine Auswahl als Selbständern-Code zu verwenden, um bestimmte Funktionen durchzuführen. Zum Beispiel, eine Maschine des eines Befehlssatz-Computers (OISC), die nur das Abziehen und den Zweig verwendet, wenn negative "Instruktion" keine indirekte Kopie (etwas wie die Entsprechung von "*a = ** b" in der c Sprache) tun kann, ohne Selbständern-Code zu verwenden.
  • Das Ändern von Instruktionen für die Schuld-Toleranz.

Die Optimierung einer zustandabhängigen Schleife

Pseudocodebeispiel:

wiederholen Sie N Zeiten {\

wenn STAAT 1 ist

nehmen Sie durch einen zu

sonst

nehmen Sie durch einen ab

tun Sie etwas mit Einem

}\

Das Selbständern des Codes würde einfach in diesem Fall eine Sache sein, die Schleife wie das umzuschreiben:

wiederholen Sie N Zeiten {\

nehmen Sie durch einen zu

tun Sie etwas mit Einem

}\

wenn STAAT {\schalten

muss

ersetzen Sie den opcode "Zunahme" oben mit dem opcode, um, oder umgekehrt abzunehmen

}\

Bemerken Sie, dass der 2-Staaten-Ersatz des opcode als leicht geschrieben werden kann

'xor var an der Adresse mit dem Wert "opcodeOf (Inc) xor opcodeOf (Dez)"'.

Auswahl dieser Lösung muss vom Wert von 'N' und der Frequenz des Zustandänderns abhängen.

Spezialisierung

Nehmen Sie eine Reihe von Statistiken wie Durchschnitt, extrema, Position von extrema, Standardabweichung an, usw. sollen für eine große Datei berechnet werden. In einer allgemeinen Situation kann es eine Auswahl von verkehrenden Gewichten mit den Daten geben, so wird jeder x mit einem w und aber nicht Test auf die Anwesenheit von Gewichten an jedem Index-Wert vereinigt, konnte es zwei Versionen der Berechnung, ein für den Gebrauch mit Gewichten und einem nicht mit einem Test am Anfang geben. Denken Sie jetzt eine weitere Auswahl, dass jeder Wert damit einen boolean vereinigt haben kann, um wichtig zu sein, ob dieser Wert ausgelassen werden soll oder nicht. Das konnte durch das Produzieren von vier Gruppen des Codes, ein für jede Versetzung und Code bloat Ergebnisse behandelt werden. Wechselweise konnten das Gewicht und die Hopser-Reihe in eine vorläufige Reihe (mit Nullgewichten für Werte verschmolzen werden, die auszulassen sind) auf Kosten der Verarbeitung, und noch gibt es bloat. Jedoch, mit der Codemodifizierung, zur Schablone, für die Statistik zu berechnen, konnte als passend der Code hinzugefügt werden, um unerwünschte Werte auszulassen, und um Gewichte anzuwenden. Es würde keine wiederholte Prüfung der Optionen geben, und auf die Datenreihe würde einmal zugegriffen, weil auch das Gewicht würde und Reihe, wenn beteiligt, auslassen.

Gebrauch als Tarnung

Das Selbständern des Codes wurde verwendet, um Kopie-Schutzinstruktionen in den 1980er Jahren plattenbasierte Programme für Plattformen wie IBM PC und Apple II zu verbergen. Zum Beispiel, auf IBM PC (oder vereinbar), würde die Diskette Laufwerk 'interne Instruktionszugriffsnummer 0x13' im Image des rechtskräftigen Programms nicht erscheinen, aber es würde ins Speicherimage des executable geschrieben, nachdem das Programm angefangen hat durchzuführen.

Das Selbständern des Codes wird auch manchmal durch Programme verwendet, die ihre Anwesenheit, wie Computerviren und ein shellcodes nicht offenbaren wollen. Viren und shellcodes, die Selbständern-Code größtenteils verwenden, tun das in der Kombination mit dem polymorphen Code. Das Ändern eines Stückes des laufenden Codes wird auch in bestimmten Angriffen wie Pufferüberschwemmungen verwendet.

Selbstverweisungsmaschinenlernsysteme

Traditionelle Maschinenlernsysteme haben einen festen, vorprogrammierten Lernalgorithmus, um ihre Rahmen anzupassen. Jedoch seit den 1980er Jahren hat Jürgen Schmidhuber mehrere Selbständern-Systeme mit der Fähigkeit veröffentlicht, ihren eigenen Lernalgorithmus zu ändern. Sie vermeiden, dass die Gefahr von katastrophalen durch das Sicherstellen selbstumschreibt, dass Selbstmodifizierungen nur überleben werden, wenn sie gemäß einer benutzergegebenen Fitness, Fehler nützlich sind oder Funktion belohnen.

Betriebssysteme

Wegen der Sicherheitsimplikationen, Code zu selbstmodifizieren, achten alle Hauptbetriebssysteme darauf, solche Verwundbarkeit zu entfernen, wie sie bekannt werden. Die Sorge ist normalerweise nicht, dass Programme sich absichtlich modifizieren werden, aber dass sie durch eine Großtat böswillig geändert werden konnten.

Als Folge der Schwierigkeiten, die durch diese Großtaten, eine OS-Eigenschaft genannt W^X verursacht werden können (für "schreiben, führen xor" durch) ist entwickelt worden, der einem Programm verbietet, jede Seite des Gedächtnisses sowohl writable als auch rechtskräftig zu machen. Einige Systeme verhindern eine writable Seite daran, jemals geändert zu werden, um rechtskräftig zu sein, selbst wenn schreiben, dass Erlaubnis entfernt wird. Andere Systeme stellen eine 'Hintertür' von Sorten zur Verfügung, vielfachen mappings einer Seite des Gedächtnisses erlaubend, verschiedene Erlaubnis zu haben. Eine relativ tragbare Weise, W^X zu umgehen, soll eine Datei mit der ganzen Erlaubnis schaffen, dann die Datei ins Gedächtnis zweimal kartografisch darstellen. Auf Linux kann man geteilte Speicherfahne von undokumentiertem SysV verwenden, um rechtskräftiges geteiltes Gedächtnis zu bekommen, ohne eine Datei schaffen zu müssen.

Trotzdem, an einem Meta-Niveau, können Programme noch ihr eigenes Verhalten durch das Ändern von Daten versorgt anderswohin modifizieren (sieh metaprogramming), oder über den Gebrauch von polymorphism.

Wechselwirkung des geheimen Lagers und Code selbstmodifizierend

Auf Architekturen ohne verbundene Daten und geheimes Instruktionslager (ein ARM und MIPS Kerne) muss die Synchronisation des geheimen Lagers durch den Ändern-Code (geheimes Erröten-Datenlager ausführlich durchgeführt werden und geheimes Instruktionslager für den modifizierten Speicherbereich ungültig machen).

In einigen Fällen führen kurze Abteilungen, Code zu selbstmodifizieren, langsamer auf modernen Verarbeitern durch. Das ist, weil ein moderner Verarbeiter gewöhnlich versuchen wird, Blöcke des Codes in seinem Gedächtnis des geheimen Lagers zu behalten. Jedes Mal, wenn das Programm einen Teil von sich umschreibt, muss der umgeschriebene Teil ins geheime Lager wieder geladen werden, das auf eine geringe Verzögerung hinausläuft, wenn der modifizierte codelet dieselbe Linie des geheimen Lagers mit dem Ändern-Code teilt, wie der Fall ist, wenn die modifizierte Speicheradresse innerhalb von einigen Bytes zu demjenigen des Ändern-Codes gelegen wird.

Das Aufhebungsproblem des geheimen Lagers auf modernen Verarbeitern bedeutet gewöhnlich, dass das Selbständern des Codes noch nur schneller sein würde, wenn die Modifizierung selten, solcher als im Fall von einer Zustandschaltung innerhalb einer inneren Schleife vorkommen wird.

Modernste Verarbeiter laden den Maschinencode, bevor sie ihn durchführen, was bedeutet, dass, wenn eine Instruktion, die auch in der Nähe vom Instruktionszeigestock ist, modifiziert wird, der Verarbeiter nicht bemerken, aber stattdessen den Code durchführen wird, wie es war, bevor er modifiziert wurde. Sieh Vorabruf hat Warteschlange eingegeben (PIQ). PC-Verarbeiter müssen Selbständern-Code richtig aus umgekehrt Vereinbarkeitsgründen behandeln, aber sie sind alles andere als beim Tun so effizient.

Der Synthese-Kern von Massalin

Der in der Doktorarbeit von Dr Alexia Massalin präsentierte Synthese-Kern ist ein winziger Kern von Unix, der einen strukturierten nimmt, oder protestieren Sie sogar orientiert, nähern Sie sich dem Selbständern des Codes, wo Code für individuellen quajects wie filehandles geschaffen wird; das Erzeugen des Codes für spezifische Aufgaben erlaubt den Synthese-Kern (wie ein JIT Dolmetscher könnte), mehrere Optimierungen wie unveränderliche Falte oder allgemeine Subausdruck-Beseitigung anwenden.

Der Synthese-Kern war äußerst schnell, aber wurde völlig im Zusammenbau geschrieben. Der resultierende Mangel an der Beweglichkeit hat die Optimierungsideen von Massalin gehindert, durch jeden Produktionskern angenommen zu werden. Jedoch weist die Struktur der Techniken darauf hin, dass sie durch eine höhere Niveau-Sprache, obgleich ein mehr Komplex gewonnen werden konnten als vorhandene Mitte Niveau-Sprachen. Solch eine Sprache und Bearbeiter konnten Entwicklung von schnelleren Betriebssystemen und Anwendungen erlauben.

Paul Haeberli und Bruce Karsh haben gegen die "Marginalisierung" protestiert, Code und Optimierung im Allgemeinen für reduzierte Entwicklungskosten zu selbstmodifizieren.

Vorteile

  • Schnelle Pfade können für eine Ausführung eines Programms gegründet werden, einige sonst wiederholende bedingte Zweige reduzierend.
  • Das Selbständern des Codes kann algorithmische Leistungsfähigkeit verbessern.

Nachteile

Das Selbständern des Codes wird von einigen als eine schlechte Praxis gesehen, weil es Code härter macht, zu lesen und aufrechtzuerhalten. Es gibt jedoch Wege, auf die selbst Modifizierung dennoch annehmbar, solcher als gehalten wird, wenn Funktionszeigestöcke dynamisch verändert werden, wenn auch die Wirkung fast zur direkten Modifizierung identisch ist. Der feine Unterschied ist in diesem Fall, dass eine Zeigestock-Variable, nicht wirkliche Programm-Instruktionen verändert wird. Die Änderung zum Zeigestock ist in diesem Fall zur Einstellung einer 'Fahne', gleichwertig (der als eine Alternative gesetzt worden sein könnte), außer dass die Fahne jedes Mal danach nicht geprüft zu werden braucht.

Am Maschineninstruktionsniveau, oft Code selbstmodifizierend, kann bedeutende Leistungsdegradierung auf modernen Verarbeitern verursachen. Der grösste Teil der üblichen Methodik, Genauigkeit im Fall vom Selbständern des Codes im Verarbeiter zu behandeln, ist ein volles Rohrleitungserröten, das eine viel steifere Strafe trägt als Zweig misprediction Wiederherstellung.

Das Selbständern des Codes kann überhaupt in einigen Umgebungen nicht verwendet werden.

Die allgemeinsten solche Umgebungen sind:

  • Anwendungssoftware, die unter einem Betriebssystem mit der strengen W^X Sicherheit läuft, kann Instruktionen in Seiten nicht durchführen, die es erlaubt wird, zu schreiben —, wird nur dem Betriebssystem selbst beiden Schreibbefehlen zum Gedächtnis erlaubt, und führen Sie später jene Instruktionen durch.
  • Viele Architektur-Mikrokontrolleure von Harvard können Instruktionen im RAM, aber nur Instruktionen im Gedächtnis nicht durchführen, dass es — ROM oder nicht selbst programmierbares Blitz-Gedächtnis nicht schreiben kann.

Siehe auch

Links


Krankenhaus-Trennung / Bambusvorhang
Impressum & Datenschutz