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-разрядный плоский адрес буфера-приемника. Используется только в случае, если 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-битного адреса