Creare un PATCHGEN

Data

by "Gz3r"

 

30/05/2001

UIC's Home Page

Published by Quequero



Hihihi...Hai scritto un sorgente davvero strano, secondo me potevi fare il tutto in modo molto più semplice, ma logicamente ogni coder ha il suo stile...Ed io di certo non posso dirti nulla visto che faccio i sorgenti più disordinati del mondo :)

 

....

E-mail: [email protected]

....

Difficoltà

(X)NewBies ( )Intermedio ( )Avanzato ( )Master

 

Una mattina mi sono svegliato ed ho pensato: siccome ho visto molti generatori di patch in giro per la rete, possibile che non ne possa fare uno anch'io? E così mi sono tolto la soddisfazione:-)


Gz3r PATCHGEN
Written by Gz3r
Allegato

Tools usati

Tasm
Ultraedit

Notizie sul programma

Questo programma è un patch generator, in pratica, viene usato per creare automaticamente le patches, cioè quei piccoli programmini che aprono il file originale e vanno a cambiare i bytes relativi alle istruzioni da modificare in maniera che il programma risulti cra**ato!!! Premetto che questo programma è stato interamente fatto in assembly ,quindi bisogna avere una conoscenza di base ....io non sono un buon coder e probabilmente il codice sarà in molte parti rindondante,in barba all'ottimizzazione:-))
 

Essay

Come funziona un patch generator ? in pratica, presi 2 files della stessa grandezza, il primo originale, ed il secondo patchato, cioè modificato in alcuni suoi bytes, li confronta, trova quali sono le differenze e qual'è il loro indirizzo all'interno del file patchato, e crea un programma eseguibile, che riesce a patchare il file originale.Forse non è molto chiaro, facciamo un esempio: prendiamo 2 files di testo (il tutto vale per qualsiasi tipo di file...infatti tutti i files si possono vedere come una sequenza di bytes:-)))) e chiamiamoli Forig.txt e Fpatched.txt ed inseriamo ad esempio dei caratteri tali che:

Forig.txt = [ ..............................] Forig sia riempito con 30 caratteri "."(punto)

Fpatched.txt = [....m..o..d..i....fi..c...ato] Fpatched sia una copia di Forig, ma alcuni caratteri siano stati modificati.

 

Il patch generator, dovrà quindi prendere in input Forig.txt e Fpatched.txt e creare in output un file .exe in grado di modificare Forig.txt, in maniera che diventi uguale a Fpatched.txt. In pratica creerà un file (chiamiamolo per ex. trasform.exe) che verrà eseguito e che farà in modo che:

 

prima di eseguire trasform.exe:

Forig.txt = [ ..............................]

Fpatched.txt = [....m..o..d..i....fi..c...ato.]

 

dopo l'esecuzione di trasform.exe:

 

Forig.txt = [....m..o..d..i....fi..c...ato.]

Fpatched.txt = [....m..o..d..i....fi..c...ato.]

 

Ok, spero di essere stato chiaro.Questo programma è scritto interamente in assembler 16 bit, per cui, dovete avere una minima conoscenza di questo linguaggio (tutes riguardanti l'assembly, li trovate proprio alla UIC :-) ).Il compilatore da me usato è il TASM 5.0, cercherò di essere più esplicativo possibile. Come detto prima, il programma è stato fatto in fretta per cui avrà qualche rindondanza, e cmq non ho utilizzato richiami a procedure ecc.L'andamento è pressochè lineare e spero sia facilmente interpretabile.Ecco il codice :

CODICE DI PATCH GENERICA (Patch.asm):

.model tiny
.code
*************************************************************************************
 
inizio: mov ax,seg iteraz METTI IN AX L'INDIRIZZO DEL SEGMENTO DI ITERAZ .ITERAZ E' IL NUMERO DI RIPETIZ DELLA PATCH (questo è un dato che il pachgen può variare)
 
mov ds,ax METTI IN DS IL SEGMENTO DI ITERAZ (NON SI PUO' FARE: mov ds,seg iteraz)
mov word ptr[indice1],0
mov di,word ptr[iteraz] IN DI
mov al,2h
mov ah,3dh FUNZIONE RELATIVA ALL'APERTURA DEL FILE
mov bx,seg nome PUNTATORE AL SEGMENTO DEL NOME DEL FILE
mov ds,bx
mov dx,offset nome PUNTATORE ALL OFFSET DEL NOME DEL FILE (ANCHE QUESTO E'UN DATO VARIATO DAL PATCHGEN)
int 21h APERTURA FILE
 
*************************************************************************************
 
push ax SALVA L'HANDLE del FILE
mov bx,offset posiz1 posiz1 E' UN'ALTRO DATO VARIABILE DAL PATCHGEN:CORRISPONDE AD UN
VETTORE CONTENENTE GLI OFFSET (LE POSIZIONI) RISPETTO ALL'INIZIO DEL FILE DI TUTTI I
BYTES DIFFERENTI DEL FILE PATCHATO
mov si,bx
 
**************************************************************************************
******AGGIORNAMENTO POSIZIONE PUNTATORE FILE RISPETTO ALL'INIZIO DEL FILE STESSO******
 
rip:mov ax,4200h FUNZIONE DI AGGIORNAMENTO PUNTATORE FILE
pop bx RIPRENDI L'HANDLE DEL FILE
push bx
mov cx,00h
mov dx,word ptr[si]
int 21h AGGIORNA POSIZIONE PUNTATORE FILE
 
**************************************************************************************
********************************SCRITTURA SUL FILE************************************
 
pop bx
push bx
mov cx,1h
mov dx,seg scrivere METTI IN AX L'INDIRIZZO DEL SEGMENTO DI scrivere.scrivere E'UN'
ALTRO DATO MODIFICABILE DAL PATCHGEN E CORRISPONDE AL DATO EFFETTIVO CHE DEVE ESSERE
MODIFICato sul file originale
mov ds,dx
mov dx,offset scrivere
add dx,word ptr[indice1]
mov ah,40h FUNZIONE DI SCRITTURA SUL FILE
int 21h
 
*************************************************************************************
 
 
inc si CICLO DI SCANSIONE DEI VETTORI CONTENENTI LA POSIZIONE E IL VALORE DEI BYTES
CHE DIFFERIVANO TRA I 2 FILES
inc si
inc word ptr[indice1]
inc word ptr[indice1]
dec di
cmp di,0
jnz rip
 
*************************************************************************************
CHIUSURA DEL FILE
 
mov ah,3eh CHIUDI IL FILE
int 21h
mov ah,4ch FINE PROGRAMMA
int 21h
*************************************************************************************

SEZIONE DATI

indice1 db 2 dup("in")
iteraz db 2 dup ("it")
scrivere db 100 dup ("scriv")
nome db 28 dup ("nome")
posiz1 db 100 dup ("posiz")
end inizio

Questa è una patch generica, cioè un programma che apre un file,punta agli indirizzi dei bytes da cambiare all'interno del file e li cambia.in pratica, mettiamo il caso dei files Forig.txt e Fpatched.txt , legge 2 vettori, scrivere e posiz1, che conterranno rispettivamente il valore dei bytes da patchare e le posizioni dei bytes stessi all'interno del file.

scrivere = ["m"]["o"]["d"]["i"]["f"]["i"]["c"]["a"]["t"]["o"]

posiz1 = [04][07][0A][0D][12][13][16][1A][1B][1C]

iteraz = 0A

iteraz conterrà il numero di iterazioni necessarie per patchare il file completamente, in questo caso 0A esadecimale (corrispondente a 10 decimale), infatti i bytes da patchare sono 10.

nome=Forig.txt"

nome conterrà il nome del file da patchare, in questo caso noi vogliamo patchare Forig.txt

ma io come vedete non ho messo alcun dato reale sulla dichiarazione dei dati nel patch.asm, perchè il numero di iterazioni, i bytes da scrivere, le posizioni di questi all'interno del file ed il nome sono variabili.Questo infatti, come ho già detto corrisponde al codice di una patch generica!!Quei dati dovranno essere variati ogniqualvolta variano i files...facciamo un esempio.Prendo altri 2 files di testo:

 

Testo1.txt = [ ...............]

Testo1patched.txt = [.m....o..d.....]

 

In questo caso i dati precedenti verranno riempiti in questo modo:

 

scrivere = ["m"]["o"]["d"]

posiz1 = [01][06][09]

iteraz = 03

nome = "Testo1.txt"

Vedete? i dati sono cambiati perchè questa volta la patch dovrà patchare solo 3 bytes affinchè:

Testo1.txt = [.m....o..d.....]

Quindi, in pratica bisognerà creare un programma che possa variare i dati all'interno del nostro programma di patch generica in maniera che la patch diventi "specifica" per quel determinato programma piuttosto che per quell'altro!!.questo è il codice del patch generator:

PATCH GENERATOR (Patchgen.asm):

.model tiny
.code
inizio:
*********************************************************************************
INSERIRE NOME 1 FILE
 
mov bx,seg ins1
mov ds,bx
mov dx,offset ins1
mov ah,9h
int 21h
mov dl,0dh
mov ah,02h i
nt 21h
mov dl,0ah
int 21h
 
*********************************************************************************
INSERIMENTO NOME 1 FILE
 
mov ah,3fh
mov bx,0
mov cx,30
mov dx,offset nm1
int 21h
mov dx,offset nm1
mov si,ax
add si,dx
mov byte ptr[si-2],0
 
*********************************************************************************
INSERIRE NOME 2 FILE
 
mov dx,offset ins2
mov ah,9h
int 21h
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
int 21h
 
*********************************************************************************
INSERIMENTO NOME 2 FILE
 
mov ah,3fh
mov bx,0
mov cx,30
mov dx,offset nome2
int 21h
mov dx,offset nome2
mov si,ax
add si,dx
mov byte ptr[si-2],0
 
*********************************************************************************
INSERIRE NOME FILE DESTINAZIONE
 
mov dx,offset ins3
mov ah,9h
int 21h
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
int 21h
 
*********************************************************************************
INSERIMENTO NOME FILE DESTINAZIONE
 
mov ah,3fh
mov bx,0
mov cx,30
mov dx,offset destin
int 21h
mov dx,offset destin
mov si,ax
add si,dx
mov byte ptr[si-2],"."
mov byte ptr[si-1],"e"
mov byte ptr[si],"x"
mov byte ptr[si+1],"e"
mov byte ptr[si+2],0
 
APRI IL PRIMO FILE
 
mov ah,1ah
mov dx,offset dta1
int 21h
mov ah,4eh
mov cx,0
mov dx,offset nm1
int 21h
jnc ava
jmp errore2
ava:mov ah,3dh
mov al,02h
mov dx,offset nm1
int 21h
mov word ptr[h1],ax
 
*********************************************************************************
APRI IL SECONDO FILE
 
mov ah,1ah
mov dx,offset dta2
int 21h
mov ah,4eh
mov cx,0
mov dx,offset nome2
int 21h
jnc ava1
jmp errore2
ava1:mov ah,3dh
mov al,02h
mov dx,offset nome2
int 21h
mov word ptr[h2],ax
 
*********************************************************************************
CONFRONTA LA GRANDEZZA DEI FILES
 
mov dx,seg dta1
mov ds,dx
mov si,offset dta1
add si,1ah
mov dx,seg dta2
mov es,dx
mov di,offset dta2
add di,1ah
cmpsw
jz avanti1
jmp errore1
avanti1:cmpsw
jz avanti3
jmp errore1
 
*********************************************************************************
 
CREO IL NUOVO FILE CHE SARA' RIEMPITO CON I DATI DI Patch.asm
avanti3:mov ah,3ch
mov cx,0
mov dx, offset destin
int 21h
mov word ptr[h3],ax
mov word ptr[ind],0
 
sub di,4
mov si,di
mov di,offset lung
movsw
movsw
mov si, word ptr[lung]
mov di,0
 
*********************************************************************************
LEGGE IL PRIMO FILE
 
avanti2:mov ax,4201h
mov bx,word ptr[h1]
mov cx,00h
mov dx,00h
int 21h mov
ah,3fh
mov bx,word ptr[h1]
mov cx,1
mov dx,offset buf1
Int 21h
 
*********************************************************************************
LEGGE IL SECONDO FILE
 
mov ax,4201h
mov bx,word ptr[h2]
mov cx,00h
mov dx,00h
int 21h
mov ah,3fh
mov bx,word ptr[h2]
mov cx,1
mov dx,offset buf2
Int 21h
*********************************************************************************
TROVA LE DIFFERENZE
 
dec si
Inc di
mov ah,buf1
mov bh,buf2
cmp si,0
jl scrit *****ERRORE*****
cmp ah,bh
jz avanti2
 
*********************************************************************************
METTE LE DIFFERENZE E LE POSIZIONI NEI DUE VETTORI DELLA PATCH GENERICA.
TALI VETTORI ANZI.TUTTO IL PROGRAMMA Patchgen.exe FA PARTE DELLA SEZIONE DATI DI QUESTO PROGRAMMA!
 
 
push si
mov si,word ptr[ind]
mov ax,0 s
ub di,1
mov word ptr psz1[si],di
inc di
inc dx
mov byte ptr[buf3],bh
mov byte ptr[buf4],00
mov bx,word ptr[buf3]
mov word ptr scritt[si],bx
inc si
inc si
mov word ptr[ind], si
inc ax
inc al
pop si
cmp si,0
jnz avanti2
 
*********************************************************************************
SCRITTURA FILE NUOVO
 
scrit:mov ax,word ptr[ind]
div byte ptr[due]
mov byte ptr[ind],al
mov ax,word ptr[ind]
mov word ptr[iteraz],ax
xor ax,ax
mov ah,40h
mov bx,word ptr[h3]
mov cx, 6bch
mov dx,seg prog
mov ds,dx
mov dx,offset prog
int 21h
jmp ok
 
*********************************************************************************
I FILES HANNO GRANDEZZA DIVERSA PATCH NON CREATA
 
errore1:mov dx,offset err1
mov ah,9h
int 21h
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
int 21h
jmp fine
 
*********************************************************************************
HAI TENTATO DI APRIRE UN FILE INESISTENTE
 
errore2:mov dx,offset err2
mov ah,9h
int 21h
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
Int 21h
jmp fine
 
*********************************************************************************
OPERAZIONE EFFETTUATA CORRETTAMENTE
 
ok: mov dx,offset okey
mov ah,9h
int 21h
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
int 21h
 
fine: mov ah,
4ch int 21h
*********************************************************************************
INIZIO AREA DATI
 
vetposiz db 100 dup(?)
vetpatch db 100 dup(?)
nome1 db 30 dup(?)
nome2 db 30 dup(?)
destin db 30 dup(?)
due db 2h
h1 db 2 dup(?)
h2 db 2 dup(?)
h3 db 2 dup(?)
dta1 db 128 dup (?)
dta2 db 128 dup (?)
lung db 4 dup(?)
indice db 2 dup(?)
buf1 db 2 dup(?)
buf2 db 2 dup(?)
buf3 db 1 dup(?)
buf4 db 1 dup (?)
ins1 db "**********************************Gz3r PATCH/GEN****************************************Inserire il nome del primo file completo di estensione:",'$'
ins2 db "********Inserire il nome del secondo file completo di estensione:",'$'
ins3 db "********inserire il nome del file destinazione (solo il nome senza estensione):",'$'
err1 db "i files hanno grandezza diversa:PATCH NON CREATA!!",'$'
err2 db "hai tentato di aprire un file inesistente!!PATCH NON CREATA!!",'$'
okey db "***********************OPERAZIONE EFFETTUATA CON SUCCESSO!! :-)) ********************",'$'
QUESTO E' Patch.exe E FA PARTE DELL'AREA DATI
 
prog db "MZ¼ [][]£~[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg1 db "?=)%%&$$£%&&%/&(/)(//[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg2 db ")()=(=)((/(/)(/()=)(((/%%$£""%&[][][][][][[][][][][][][][][][][][][][][][][][][][][]"
prg3 db "?=)%%&$$£%&&%/&(/)(//[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg4 db " [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg5 db " &$$£%&&%/&(/(/)(/()=)(((/%%$£[][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg6 db "B[S¹[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
ind db "inin"
iteraz db "itit"
scritt db "scrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscriv
scrivscrivscrivscrivscrivscrivscrivscrivscr"
scr2 db "ivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscriv
scrivscrivscrivscrivscrivscrivscrivscrivs"
scr3 db "crivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscr
ivscrivscrivscrivscrivscrivscrivscrivscri"
scr4 db "vscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivs
crivscrivscrivscrivscrivscrivscrivscrivscrivscriv"
nm1 db "nomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenom
enomenomenomenomenomenomenome"
psz1 db"posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpos
izposizposizposizposizposizposizposizposizposiz"
psz2 db"posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpos
izposizposizposizposizposizposizposizposiz"
psz3 db "posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpo
sizposizposizposizposizposizposizposizposizposiz"
psz4 db "posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpo
sizposizposizposizposizposizposiz"

FINE AREA DATI

**************************************************************************************************************************

end inizio
 

In pratica, appena sopra vedete l'area dati è stato fatto in questo modo:

ho preso quindi Patch.asm , che corrisponde al codice di una patch generica, cioè con dati non inizializzati (o meglio, alcuni dati, come i 2 vettori li ho inizializzati mettendo una sequenza di lettere ,per es. nome è riempito inizialmente con la sequenza "nomenomenome..ecc.), lo ho compilato e linkato ed ho quindi creato l'exe della patch generica (chiamiamolo Patch.exe). Poi ho aperto con un editor esadecimale Patch.exe, ed ho copiato (Ctrl-C) interamente i codici esadecimali relativi a dati e codice di Patch.exe nel codice dati di Patchgen.asm, aperto anch'esso con l'editor esadecimale (Ctrl-V). Ho in pratica inserito il codice "eseguibile" di Patch.exe (scusate la ripetizione), all'interno della sezione dati di Patchgen.asm.In questo modo il Patchgen potrà variare i dati fittizi della patch generica con i dati reali e potrà quindi creare un nuovo file eseguibile copiando proprio questa sezione di dati (corrispondente al Patch.exe) direttamente sul disco fisso.Io ho fatto così per creare questo tipo di patch-generator....sinceramente mi sono inventato io questo approccio, non attingendo a nessuna fonte...non so se è l'approccio giusto o se si fa sempre così ....ho provato e basta!!:-)).Cerchiamo di spiegare meglio il concetto in maniera visuale:questo è uno schema riassuntivo del nostro Patchgen.asm

 

Patchgen.asm :

SEZIONE CODICE

.model tiny

.code

------ecc.

------ecc.

------ecc.

mov ah,4ch

int 21h

SEZIONE DATI

Vetposiz db 100 dup(?)

-------ecc.

-------ecc

*************************************************************************************************

.........da quì abbiamo fatto un copia/incolla del prog. "patch.exe"
 
prog db "MZ¼ [][]£~[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg1 db "?=)%%&$$£%&&%/&(/)(//[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg2 db ")()=(=)((/(/)(/()=)(((/%%$£""%&[][][][][][[][][][][][][][][][][][][][][][][][][][][]"
prg3 db "?=)%%&$$£%&&%/&(/)(//[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg4 db " [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg5 db " &$$£%&&%/&(/(/)(/()=)(((/%%$£[][][][][][][][][][][][][][][][][][][][][][][][][][][]"
prg6 db "B[S¹[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]"
ind db "inin"
iteraz db "itit"
scritt db "scrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscriv
scrivscrivscrivscrivscrivscrivscrivscrivscr"
scr2 db "ivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscriv
scrivscrivscrivscrivscrivscrivscrivscrivs"
scr3 db "crivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscr
ivscrivscrivscrivscrivscrivscrivscrivscri"
scr4 db "vscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivscrivs
crivscrivscrivscrivscrivscrivscrivscrivscrivscriv"
nm1 db "nomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenomenom
enomenomenomenomenomenomenome"
psz1 db"posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpos
izposizposizposizposizposizposizposizposizposiz"
psz2 db"posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpos
izposizposizposizposizposizposizposizposiz"
psz3 db "posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpo
sizposizposizposizposizposizposizposizposizposiz"
psz4 db "posizposizposizposizposizposizposizposizposizposizposizposizposizposizposizposizpo
sizposizposizposizposizposizposiz"

*************************************************************************************************

 
end inizio

In pratica, il codice che vedete in giallo tra gli asterischi rossi, e che si trova all'interno del nostro Patchgen.asm è stato ottenuto facendo un copia/incolla del programma patch.exe ottenuto dopo la compilazione del codice di Patch.asm.Alcuni caratteri non erano visualizzabili su questa pagina html e li ho sostituiti con dei caratteri"finti" per dare il senso all'immagine.Quindi,Non fate il copia/incolla del listato di Patchgen.asm. Attenzione perchè Il programma funziona per files con lunghezza ridotta, sicuramente fino ai 32KB...non ho fatto le prove esatte, cmq, oltre quella grandezza c'è un errore in un confronto che ho evidenziato sul listato con la dicitura *****ERRORE***** e che non ho avuto tempo di risolvere,e ,sempre per il fatto che il tempo mi mancava non ho messo nel listato alcuni controlli in input,ma l'importante è capire il funzionamento.!! Spero di essere stato abbastanza chiaro nella spiegazione...ammetto di aver ripetuto più volte i concetti per farmi capire...a volte non mi spiego bene! :-p

 

Gz3r

Note finali

Saluto Acid_Leo, che è l'unico che conosco all'interno di #crack-it e naturalmente Que e tutti gli altri.

Disclaimer

Vorrei ricordare che il software va comprato e  non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento è stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.