Självmodifierande kod (SMC) är en programmeringsteknik där en applikation skapar eller ändrar en del av sin programkod vid körning. Sådan kod används vanligtvis i program skrivna för en processor med en von Neumann- minnesorganisation.
Vid tidpunkten för ändringen är metoden uppdelad i:
I båda fallen sker ändringen direkt i maskinkoden när nya instruktioner skriver över gamla (t.ex. en villkorlig gren JZ , JNZ , JE , JNE , etc. ersätts av en ovillkorlig gren JMP eller NOP ). IBM /360 och Z/Architecture - instruktionsuppsättningarna har en EXECUTE (EX) -instruktion som skriver över målinstruktionen (inspelad i den andra byten av EX-instruktionen) med de minst signifikanta 8 bitarna av register 1. På dessa arkitekturer implementerar den en standard, legitim metod för att tillfälligt ändra instruktioner .
Huvudapplikationer för självmodifierande kod:
I Harvard-arkitekturen är minne för kod och minne för data separerade. Följaktligen blir arbetet med självmodifierande kod mycket mer komplicerat i dem. Även om x86- arkitekturen definieras som von Neumann (enkelkod och dataminne) har de flesta moderna processorer separata cacheområden för kod och data. Samtidigt stöder kodcachen inte skrivning, och när man ändrar det cachade minnesområdet, antingen en partiell eller fullständig återställning av kodcachen (x86) eller en explicit instruktion till processorn att återställa kodcachen ( SPARC ) kan krävas. På grund av detta kan nymodifierad kod köras långsammare eller kräva ytterligare kommandon för att fungera korrekt. Genom att ändra koden återställs även processorpipelinen . [2]
Vissa idéer om Harvard-arkitekturen är också implementerade i operativsystemet (till exempel Data Execution Prevention i Windows, W^X i OpenBSD ) och i processorer (för x86 - NX-bitar och liknande). I dessa implementeringar kan enskilda minnesbitar markeras som icke-körbara (dvs data) eller som körbara men inte modifierbara (dvs kod utan rätt att ändra). Användningen av självmodifierande kod i sådana programmeringsmiljöer är komplicerad, eftersom den antingen måste placeras i ett oskyddat minnesområde (ibland är det här området stacken ), eller uttryckligen inaktivera skyddet för att koden ska ändras .
Perl , PHP och Python tillåter ett program att skapa ny kod vid körning och köra den med hjälp av eval-funktionen, men tillåter inte att befintlig kod modifieras själv (interaktivt python-skal) :
>>> x = 1 >>> eval ( 'x + 1' ) 2 >>> eval ( 'x' ) 1Illusionen av modifiering (förutsatt att ingen inbyggd kod faktiskt ändras) uppnås genom att ändra funktionspekaren, som i detta JavaScript- exempel:
var f = funktion ( x ) { return x + 1 }; alert ( f ( 0 )); //ett f = ny funktion ( 'x' , 'retur x + 2' ); // tilldela en ny definition till f alert ( f ( 0 )); //2