Восстановление данных. Практическое руководство
CMP byte [SI+4], 05hJZ LOAD_CHS_EXT ; Это расширенная таблица разделов; в формате CHSCMP byte [SI+4], 0FhJZ LOAD_LBA_EXT ; Это расширенная таблица разделов; в формате LBAADD SI, 10h ; Переходим на следующий разделCMP SI, 1EEhJNA read_all_partitions ; Читаем все разделы один за другим...buf rb 512 ; Буфер на 512 байтЗапись сектора в режиме CHS происходит практически точно так же, только регистр
равен неAH, a02h. С режимом LBA разобраться намного сложнее, но мы, как настоящие хакеры, его обязательно осилим.03hЧтение сектора осуществляется функцией
(42h). В регистрAH = 42h, как и прежде, заносится номер привода, а вот регистровая параDLуказывает на адресный пакет (disk address packet), представляющий собой продвинутую структуру формата, описанного в табл. 5.4.DS:SIТаблица 5.4. Формат адресного пакета, используемый для чтения и записи секторов в режиме LBA
Смещение Тип Описание 00hBYTEРазмер пакета — или10h18h01hBYTEПоле зарезервировано и должно быть равно нулю 02hWORDСколько секторов читать 04hDWORD32-разрядный адрес буфера-приемника в формате seg:offs08hQWORDСтартовый номер сектора для чтения 10hQWORD64-разрядный плоский адрес буфера-приемника. Используется только в случае, если 32-разрядный адрес равен FFFF:FFFFКод, читающий сектор в режиме LBA, в общем случае выглядит так, как показано в листинге 5.7.
Листинг 5.7. Код, осуществляющий чтение сектора с диска в режиме LBA
MOV DI, 1BEh ; Перейти к первому разделуMOV AX, CS ; Настраиваем...MOV buf_seg ; ...сегментMOV EAX, [DI+08h] ; Смещение partition относительно; начала разделаADD EAX, EDI ; EDI должен содержать номер сектора; текущего MBRMOV [X_SEC] ;...read_all_partitions:MOV АН, 42h ; Читать сектор в режиме LBAMOV DL, 80h ; Читать с первого дискаMOV SI, dap ; Смещение адресного пакета INT 13hJC error ; Ошибка чтения...dap:packet_size db 10h ; размер пакета 10h байтreserved db 00h ; "Заначка" для будущих расширенийN_SEC dw 01h ; Читаем один секторbuf_seg dw 00h ; Сюда будет занесен сегмент буфера-приемникаbuf_off dw buf ; Смещение буфера-приемникаX_SEC dd 0 ; Сюда будет занесен номер сектора для чтенияdd 0 ; Реально не используемый хвост; 64-битного адресаbuf rb 512 ; Буфер на 512 байтЗапись осуществляется аналогично чтению, только регистр
содержит неAH, a42h. Регистр43hопределяет режим: если бит 0 равен 1, BIOS выполняет не запись, а ее эмуляцию. Бит 2, будучи взведенным, задействует запись с проверкой. Если регистрALравен 0, выполняется обыкновенная запись по умолчанию.ALТеперь, освоившись с дисковыми прерываниями, перейдем к обсуждению остальных аспектов программирования.
Создаем код загрузчикаЛучше всего загрузчики программируются на FASM. С точки зрения ассемблера загрузчик представляет собой обыкновенный двоичный файл, предельно допустимый объем которого составляет
(443) байт. Немного? Но не будем спешить с выводами. Всякий раздел всегда начинается с начала цилиндра, а это значит, что между концом MBR и началом раздела имеется, по меньшей мере, n свободных секторов, где1BBh. Практически все современные винчестеры имеют по 64 сектора на дорожку, что дает нам:n == sectors per trackбайт или приблизительно 32 Кбайт. Да в этот объем даже графический интерфейс с мышью уместить можно! Однако делать этого мы не будем. Настоящие хакеры работают в текстовом режиме с командной строкой.443 + 63*512 == 32 699Как уже говорилось, BIOS загружает MBR по адресу
, поэтому в начале ассемблерного кода должна стоять директива7C00h, а еще —ORG 7C00h, ведь загрузчик выполняется в 16-разрядном реальном режиме. Позже, при желании, он может перейти в защищенный режим, но это будет уже потом. Не будем лезть в такие дебри.USE16