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

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

стр.

задают номер сектора, оставшиеся биты регистра >CL и восемь битов регистра >CH определяют номер цилиндра, который мы хотим прочитать. Регистровая пара >ES:BX указывает на адрес буфера-приемника. Вот, собственно говоря, и все. После выполнения команды >INT 13h считываемые данные окажутся в буфере, а если произойдет ошибка (например, головка "споткнется" о BAD-сектор), то BIOS установит флаг переноса (carry flag), и мы будем вынуждены либо повторить попытку, либо вывести грустное сообщение на экран.

Код этой программы на языке ассемблера представлен в листинге 5.6.

Листинг 5.6. Код, считывающий загрузочный сектор или расширенную таблицу разделов

>MOV SI, 1BEh ; Перейти к первому разделу

>MOV AX, CS   ; Настраиваем ES

>MOV ES, AX

>MOV BX, buf  ; Смещение буфера

>...

>read_all_partitions:

> MOV AX, bud            ; Читать 1 сектор с диска

> MOV DL, 80h            ; Читать с первого диска

> MOV DH, [SI+1]         ; Стартовый номер головки

> MOV CX, [SI+2]         ; Стартовый сектор с цилиндром INT 13h

> JC error               ; Ошибка чтения


> ;Обрабатываем считанный boot-сектор или расширенную таблицу разделов

> ;===================================================================

> ;

> CMP byte [SI], 80h

> JZ LOAD_BOOT            ; Это загрузочный сектор

>                         ; Передаем на него управление


> CMP byte [SI+4], 05h

> JZ LOAD_CHS_EXT         ; Это расширенная таблица разделов

>                         ; в формате CHS


> CMP byte [SI+4], 0Fh

> JZ LOAD_LBA_EXT         ; Это расширенная таблица разделов

>                         ; в формате LBA


> ADD SI, 10h             ; Переходим на следующий раздел

> CMP SI, 1EEh

> JNA read_all_partitions ; Читаем все разделы один за другим

>...>buf rb 512               ; Буфер на 512 байт

Запись сектора в режиме CHS происходит практически точно так же, только регистр >AH равен не >02h, a >03h. С режимом LBA разобраться намного сложнее, но мы, как настоящие хакеры, его обязательно осилим.

Чтение сектора осуществляется функцией >42h (>AH = 42h). В регистр >DL, как и прежде, заносится номер привода, а вот регистровая пара >DS:SI указывает на адресный пакет (disk address packet), представляющий собой продвинутую структуру формата, описанного в табл. 5.4.


Таблица 5.4. Формат адресного пакета, используемый для чтения и записи секторов в режиме LBA

СмещениеТипОписание
>00h>BYTEРазмер пакета — >10h или >18h
>01h>BYTEПоле зарезервировано и должно быть равно нулю
>02h>WORDСколько секторов читать
>04h>DWORD32-разрядный адрес буфера-приемника в формате >seg:offs
>08h>QWORDСтартовый номер сектора для чтения
>10h>QWORD64-разрядный плоский адрес буфера-приемника. Используется только в случае, если 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 должен содержать номер сектора

>                  ; текущего MBR

>MOV [X_SEC]       ;

>...

>read_all_partitions:

> MOV АН, 42h      ; Читать сектор в режиме LBA

> MOV DL, 80h      ; Читать с первого диска

> MOV SI, dap      ; Смещение адресного пакета INT 13h

> JC 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 содержит не >42h, a >43h. Регистр >AL определяет режим: если бит 0 равен 1, BIOS выполняет не запись, а ее эмуляцию. Бит 2, будучи взведенным, задействует запись с проверкой. Если регистр >AL равен 0, выполняется обыкновенная запись по умолчанию.


стр.

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