Восстановление данных - страница 45

Шрифт
Интервал

стр.

Теперь, освоившись с дисковыми прерываниями, перейдем к обсуждению остальных аспектов программирования.

Создаем код загрузчика

Лучше всего загрузчики программируются на FASM. С точки зрения ассемблера загрузчик представляет собой обыкновенный двоичный файл, предельно допустимый объем которого составляет >1BBh (443) байт. Немного? Но не будем спешить с выводами. Всякий раздел всегда начинается с начала цилиндра, а это значит, что между концом MBR и началом раздела имеется, по меньшей мере, n свободных секторов, где >n == sectors per track. Практически все современные винчестеры имеют по 64 сектора на дорожку, что дает нам: >443 + 63*512 == 32 699 байт или приблизительно 32 Кбайт. Да в этот объем даже графический интерфейс с мышью уместить можно! Однако делать этого мы не будем. Настоящие хакеры работают в текстовом режиме с командной строкой.

Как уже говорилось, BIOS загружает MBR по адресу >7C00h, поэтому в начале ассемблерного кода должна стоять директива >ORG 7C00h, а еще — >USE16, ведь загрузчик выполняется в 16-разрядном реальном режиме. Позже, при желании, он может перейти в защищенный режим, но это будет уже потом. Не будем лезть в такие дебри.

Обнаружив загрузочный раздел (а обнаружить это можно по флагу >80h, находящемуся по нулевому смещению от начала раздела), загрузчик должен считать первый сектор этого раздела, поместив его в памяти по адресу >0000:7C00h, то есть в точности поверх своего собственного тела. А вот это уже нехорошо! И чтобы не вызвать крах системы, загрузчик должен заблаговременно перенести свое тело по другому адресу, что обычно осуществляется командой >MOVSB. Копироваться можно по любому из адресов памяти — от >0080:0067h до >9FE00h. Память, расположенную ниже >0080:0067h, лучше не трогать, так как здесь находятся вектора прерываний и системные переменные BIOS, а от >A000h и выше начинается область отображения ПЗУ, так что предельно доступный адрес равен >A000h - 200h (размер сектора) == 9FE00h.

Не забывайте, что трогать регистр >DL ни в коем случае нельзя, поскольку в нем передается номер загрузочного привода. Некоторые загрузчики содержат ошибку, всегда загружаясь с первого жесткого диска, и это в то время, как BIOS уже больше 10 лет как позволяют менять порядок загрузки, и потому загрузочным может быть любой привод.

По правде говоря, FASM — это единственный известный мне ассемблер, "переваривающий" команду дальнего вызова >JMP 0000:7C00h напрямую. Все остальные ассемблеры заставляют извращаться приблизительно так: >PUSH offset_of_target/PUSH segment_of_target/RETF. Здесь мы заталкиваем в стек сегмент и смещение целевого адреса и выполняем дальний >RETF, переносящий нас на нужное место. Еще можно воспользоваться самомодифицирующимся кодом, собрав команду >JMP FAR "вручную", или просто расположить целевой адрес в одном сегменте с исходным адресом (например, >0000:7C00h>0000:7E00h). Однако эти подходы муторны и утомительны.

В общем, скелет нашего загрузчика будет выглядеть так, как показано в листинге 5.8.

Листинг 5.8. Скелет простейшего загрузчика, написанный на FASM

>use16

>ORG 7C00h

>CLD            ; Копируем слева направо

>               ; (в сторону увеличения адресов)

>MOV SI,7C00h   ; Откуда копировать

>MOV DI,7E00h   ; Куда копировать

>MOV CX,200h    ; Длина сектора

>REP MOVSB      ; Копируем


>; // Выбираем раздел, который мы хотим загрузить,

>; // считываем его в память по адресу 0000:7C00h

>; // (см. листинги 5.7 и 5.6)


>JMP 0000:7C00h ; Передаём управление на загрузочный сектор

Записываем загрузчик в главную загрузочную запись

Под старушкой MS-DOS записать свой загрузчик в MBR было просто. Для этого достаточно дернуть прерывание >INT 13h, функция >03h (запись сектора). Но под Windows NT этот прием уже не работает, и приходится прибегать к услугам функции >CreateFile. Если вместо имени открываемого файла указать название устройства, например, >\\.\PHYSICALDRIVE0 (первый физический диск), мы сможем свободно читать и записывать его сектора вызовами >ReadFile и >WriteFile соответственно. При этом флаг >dwCreationDisposition должен быть установлен на значение


стр.

Похожие книги