Cod auto-modificabil

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 6 iulie 2019; verificările necesită 3 modificări .

Codul auto-modificabil (SMC) este o tehnică de programare în care o aplicație creează sau modifică o parte din codul programului său în timpul rulării. Un astfel de cod este de obicei folosit în programele scrise pentru un procesor cu o organizare de memorie von Neumann .

Până la momentul modificării, metoda este împărțită în:

În ambele cazuri, modificarea are loc direct în codul mașinii atunci când instrucțiunile noi le suprascriu pe cele vechi (de exemplu, o ramură condiționată JZ , JNZ , JE , JNE , etc. sunt înlocuite cu o ramură necondiționată JMP sau NOP ). Seturile de instrucțiuni IBM/360 și Z/Architecture au o instrucțiune EXECUTE (EX) care suprascrie instrucțiunea țintă (înregistrată în al doilea octet al instrucțiunii EX) cu cei 8 biți mai puțin semnificativi din registrul 1. Pe aceste arhitecturi, implementează un metodă standard, legitimă pentru modificarea temporară a instrucțiunilor.

Numire

Principalele aplicații ale codului cu auto-modificare:

Aplicabilitate la procesoare cu arhitectură Harvard

În arhitectura Harvard , memoria pentru cod și memoria pentru date sunt separate. În consecință, munca codului de auto-modificare devine mult mai complicată în ele. Deși arhitectura x86 este definită ca von Neumann (cod unic și memorie de date), majoritatea procesoarelor moderne au zone de cache separate pentru cod și date. În același timp, memoria cache a codului nu acceptă scrierea și, atunci când se schimbă zona de memorie cache, fie o resetare hardware parțială sau completă a memoriei cache a codului (x86), fie o instrucțiune explicită către procesor pentru a reseta memoria cache ( SPARC ) poate fi cerut. Din acest motiv, codul nou modificat poate rula mai lent sau poate necesita comenzi suplimentare pentru a funcționa corect. De asemenea, modificarea codului resetează conducta procesorului . [2]

De asemenea, unele idei ale arhitecturii Harvard sunt implementate în sistemul de operare (de exemplu, Data Execution Prevention în Windows, W^X în OpenBSD ) și în procesoare (pentru x86 - NX bit și altele asemenea). În aceste implementări, bucățile individuale de memorie pot fi marcate ca neexecutabile (adică, date) sau ca executabile, dar nemodificabile (adică, cod fără drept de modificare). Utilizarea codului cu auto-modificare în astfel de medii de programare este complicată, deoarece trebuie fie să fie amplasat într-o zonă neprotejată a memoriei (uneori această zonă este stiva ), fie să dezactiveze în mod explicit protecția pentru ca codul să fie schimbat. .

Utilizare

Limbi interpretate

Perl , PHP și Python permit unui program să creeze cod nou în timpul execuției și să-l execute folosind funcția eval, dar nu permit codului existent să se automodifice (shell python interactiv) :

>>> x = 1 >>> eval ( 'x + 1' ) 2 >>> eval ( 'x' ) 1

Iluzia modificării (presupunând că niciun cod nativ nu este schimbat efectiv) se realizează prin schimbarea indicatorului funcției, ca în acest exemplu JavaScript :

var f = function ( x ) { return x + 1 }; alertă ( f ( 0 )); //unu f = Funcție nouă ( 'x' , 'return x + 2' ); // atribuie o nouă definiție lui f alert ( f ( 0 )); //2

Vezi și

  • Metaprogramarea
  • Monkey Patch - înlocuirea dinamică a procedurilor executabile ale programului în timpul execuției fără modificarea codului sursă.

Note

  1. Vezi, de exemplu, codul sursă Doom Legacy , caracteristica ASM_PatchRowBytes.
  2. Kaspersky, paragraf cu „Procesorii familiei Pentium ..”

Link -uri