большое количество разнокалиберных накопителей, абстрагируясь от конструктивных особенностей каждой конкретной модели. Поэтому будем действовать через нее, а точнее, через интерфейс прерывания INT 13h
.
Попробуем прочитать сектор с диска в режиме CHS. Действовать нужно из самой MBR или из 'голой' MS-DOS, иначе у нас ничего не получится, ведь Windows NT блокирует прямой доступ к диску даже из режима эмуляции MS-DOS.
Номер функции заносится в регистр AH
. В случае чтения он равен двум. Регистр AL
отвечает за количество обрабатываемых секторов. Так как мы собираемся читать по одному сектору за операцию, занесем сюда единицу. Регистр DH
хранит номер головки, a DL
— номер привода (80h
— первый жесткий диск, 81h
— второй и т.д.). Пять младших битов регистра CL
задают номер сектора, оставшиеся биты регистра 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.
Смещение | Тип | Описание |
---|---|---|
00h | BYTE | Размер пакета — 10h или 18h |
01h | BYTE | Поле зарезервировано и должно быть равно нулю |
02h | WORD | Сколько секторов читать |
04h | DWORD | 32-разрядный адрес буфера-приемника в формате seg:offs |
08h | QWORD | Стартовый номер сектора для чтения |
10h | QWORD | 64-разрядный плоский адрес буфера-приемника. Используется только в |