(`._.[o.OKinG-InFeTO.o]._.)


Vai ai contenuti

Virus che risiedano in memoria

VR

Virus che risiedono in memoria

 

I virus non residenti in memoria possono "agire" - sia per quanto riguarda

l'infezione che per quanto riguarda gli effetti collaterali - solo nel momento in

cui viene eseguito un file infetto.

I virus residenti in memoria, invece, non appena viene eseguito un file infetto,

si copiano in memoria per poter essere eseguiti assieme ad alcune funzioni del DOS,

i cosiddetti INTERRUPT.

 

- Cosa sono gli interrupt e come funzionano? -

 

Gli interrupt sono le funzioni basilari che sono fornite in parte dal BIOS in parte

dal DOS.

Gli interrupt sono numerati, e per eseguire un interrupt in assembler (piu' o meno

come in tutti gli altri linguaggi) l'istruzione e' la seguente:

 

INT xx

 

dove xx e' il numero dell'interrupt che vogliamo eseguire.

Alcuni interrupt sono "raccolte" di funzioni, e occorre scegliere la sottofunzione

da eseguire tramite il registro AH. Per molti interrupt occorre fornire dei dati in

input tramite i vari registri... e qui preferisco non dilungarmi perche' se dovessi

descrivervi ogni interrupt e come funziona ci metterei diversi giorni.

Comunque, gli interrupt 0h - 1Fh sono forniti dal BIOS, mentre quelli dal 20h in

poi sono forniti dal DOS.

Facciamo un esempio... diciamo che voglio scrivere qualcosa sullo schermo. Devo

utilizzare l'interrupt 21h, sottofunzione 09h, con la stringa che voglio stampare

(terminata dal caratttere "$") all'indirizzo di memoria DS:DX. Nel mio listato

dovro' scrivere:

 

Mia_Stringa db "Flamer has been here",13,10,'$' ;Questa e' la stringa che

;voglio stampare

MOV DX,offset Mia_Stringa ;Faccio puntare DS:DX a Mia_Stringa

MOV AX,segment Mia_Stringa

MOV DS,AX

MOV AH,09h ;Sottofunzione 9h

INT 21h ;Interrupt 21h

 

...semplice, no?

La stessa cosa in Turbo Pascal sarebbe:

 

var Mia_Stringa:array [1..23] of char;

Reg:TRegisters;

[...]

Mia_Stringa:='Flamer has been here'+#13+#10+'$';

Reg.DX:=ofs(Mia_Stringa);

Reg.DS:=seg(Mia_Stringa);

Reg.AH:=$09;

intr($21,Reg);

 

Ma in realta' come funziona un interrupt?... Cosa effettivamente succede quando

viene chiamato un interrupt?...

In realta' questo e' quello che succede:

1) Viene fatto un push di tutti i registri, e dell'indirizzo di memoria da cui e'

stato chiamato l'interrupt.

2) Il computer cerca nella tabella degli interrupt l'indirizzo di memoria a cui si

trova la routine di gestione dell'interrupt, e salta a quell'indirizzo.

La tabella degli interrupt si trova nella sezione di memoria che va da 0000:0000 a

0000:0400, in cui ogni doubleword (4 bytes) rappresenta un indirizzo per un

interrupt.

Per cui ad esempio l'indirizzo per la chiamata all'interrupt 0h sta in 0000:0000,

quello per l'interrupt 1h sta a 0000:0004, e cosi' via...

Modificando questa tabella e' possibile "aggangiare" un interrupt, reindirizzandolo

su un altra locazione di memoria, con l'effetto di sostituire la routine di

interrupt con una creata da noi, che al suo interno puo' anche richiamare la

routine originale dell'interrupt. L'effetto di tutto cio' e' che l'interrupt viene

eseguito normalmente, e in piu' succede anche qualcos'altro... ad esempio

l'esecuzione del codice di un virus.

 

Il fatto che esistano interrupt che vengono chiamati nei momenti piu' svariati

(pressione di un tasto, esecuzione di un file, lettura di un settore del disco,

ecc...) torna tutto a vantaggio dei virus, che possono ad esempio infettare i file

quando vengono eseguiti, senza bisogno di impiegare routine (e dimensioni) per

cercare i file infettabili all'interno delle varie directory...

Oppure anche intercettare comandi tipo DIR, e modificarne l'output in modo che le

dimensioni di eventuali file infetti non risultino sospette...

In definitiva, un virus che riesce ad aggangiarsi ad un interrupt viene a trovarsi

ad un livello piu' basso del DOS stesso, ed ha quindi la possibilita' di essere

molto piu' efficace di un virus non residente in memoria.

 

- Preesecuzione e postesecuzione -

 

Ma vediamo piu' in dettaglio come e' fatta una routine aggangiata ad un interrupt.

Esistono 2 metodi di aggangiamento di un interrupt: preesecuzione e postesecuzione.

Nel primo caso la routine chiama il vecchio interrupt e poi riprende il controllo

(eventualmente modificando i dati in output), mentre nel secondo l'interrupt

originale viene chiamato al termine della routine.

Trattare il secondo caso e' molto piu' facile, poiche' la chiamata all'interrupt

avviene molto semplicemente con un JMP FAR, al termine della nostra routine.

Infatti la routine originale termina gia' da se' con l'istruzione IRET (Interrupt

RETurn), che provvede a restituire il controllo al programma che aveva chiamato

l'interrupt e a ripristinare i registri dallo stack.

Nel caso della preesecuzione, invece, bisogna fare i conti con un piccolo problema.

Infatti la nostra routine chiama l'interrupt originale, ma poi il controllo non

deve tornare al programma che ha chiamato l'interrupt, ma alla nostra routine. Per

evitare inconvenienti e' percio' necessario simulare una chiamata ad interrupt in

questo modo:

 

PUSHF ;Salva tutti i registri nello stack

CALL FAR PTR xxxx:yyyy ;Esegue la chiamata all'interrupt originale

 

NB: Quando il vostro virus si copia in memoria deve sostituire xxxx:yyyy con il

puntatore che e' stato sostituito nella tabella degli interrupt, cioe' l'indirizzo

della routine di interrupt originale!!

Dopodiche' siamo liberi di inserire tutte le modifiche che vogliamo all'output

dell'interrupt e i vari effetti collaterali del virus, terminando la routine con:

 

IRET

 

per restituire il controllo al programma che aveva chiamato l'interrupt (ora si'!!)

 

- "Ma in memoria DOVE???" -

 

Riassumendo un virus residente in memoria deve:

1) Controllare di non essere gia' presente in memoria (lo si puo' fare controllando

l'indirizzo dell'interrupt aggangiato e verificando se i primi byte a

quell'indirizzo corrispondono ai primi byte del virus)

2) Scrivere il suo codice in memoria

3) Eventualmente leggere e salvare il vecchio indirizzo dell'interrupt da

aggangiare

4) Modificare la tabella degli interrupt per farlo puntare alla locazione di

memoria in cui si trova il codice del virus

 

Non vi sara' pero' sfuggito un fatto abbastanza importante, e percepisco gia' la

domanda che state per pormi.

Ma come fare per essere sicuri che il mio virus in memoria sia al sicuro, cioe'

che non venga sovrascritto da qualche altro programma (con conseguenze disastrose)?

Be'... diciamo che esistono svariati metodi per ovviare al problema. Il piu'

semplice e' quello di ricorrere all'interrupt 27h del DOS, che lascia in memoria il

programma (ma ne termina l'esecuzione e lo rende facilmente visibile). Un altro

metodo e' quello di andare ad occupare un'area di memoria che molto difficilmente

verra' utilizzata da un altro programma (come ad esempio l'area in cima alla

tabella degli interrupt, oppure in fondo alla memoria "bassa" cioe' proprio sotto i

640K).

Creative Commons License
Questo sito pubblicato sotto una Licenza Creative Commons

Home Page | Regole dell'Hacker | Contattaci | HkG | VR | Video TuToRial | HkG M | C++ | Wdw$ X | Mappa del sito


Sito protetto da CoPyRiGhT 2008/2009 | [email protected]

Torna ai contenuti | Torna al menu