Стряпаем MBR Крис Касперски ака мыщъх Хакер, номер #079, стр. 079-114-3 Стандартный загрузчик позволяет запускать системы только из Основной Таблицы Разделов. Цепочку MBR'ов он не анализирует. В своем загрузчике мы исправим этот недостаток. [интерфейс INT 13h] Управлять дисками можно как через порты ввода/вывода, так и через BIOS. Порты очень могущественны и интересны, однако BIOS программируется на порядок проще, к тому же он поддерживает множество разнокалиберных накопителей, абстрагируя нас от конструктивных особенностей каждой конкретной модели винчестера. В общем, мы будем действовать через него, а точнее через интерфейс прерывания INT 13h. Для начала попробуем прочитать сектор с диска в CHS-mode. Естественно, нужно действовать из самого MBR или из «голой» MS-DOS, иначе ничего не получится, так как Windows NT блокирует прямой доступ к диску даже из режима «Эмуляция MS-DOS»! Номер функции заносится в регистр AH. В случае чтения он равен двум. Регистр AL отвечает за количество обрабатываемых секторов. Поскольку мы собираемся читать по одному сектору за раз, занесем сюда единицу. Регистр DH хранит номер головки, а DL — номер привода (80h — первый жесткий диск, 81h — второй и так далее). Пять младших битов регистра CL задают номер сектора, оставшиеся биты регистра CL и восемь битов регистра CH определяют номер цилиндра, который мы хотим прочитать. Регистровая пара ES:BX указывает на адрес буфера-приемника. Вот, собственно говоря, и все. После выполнения команды INT 13h данные из читаемого сектора окажутся в буфере, а если произойдет ошибка (например головка споткнется о BAD-сектор), BIOS установит флаг переноса (carry flag) и мы будем вынуждены либо повторить попытку, либо вывести грустное сообщение на экран. На ассемблере все это дело выглядит так: [код, считывающий загрузочный сектор или Расширенную Таблицу Разделов] MOV SI, 1Beh ; на первый partition MOV AX, CS ; настраиваем ES MOV ES, AX ; MOV BX, buf ; смещение буфера … read_all_partitions: MOV AX, 0201h ; читать 1 сектор с диска MOV DL, 80h ; читать с первого диска MOV DH, [SI+1] ; стартовый номер головки MOV CX, [SI+2] ; стартовый сектор с цилиндром INT 13h JC error ; ошибка чтения ; обрабатываем считанный boot-сектор или extended partitions ; ========================================================== ; CMP byte [SI], 80h JZ LOAD_BOOT ; это загрузочный раздел ; передаем на него управление CMP byte [SI+4], 05h JZ LOAD_CHS_EXT ; это Расширенная Таблица Разделов в CHS-формате CMP byte [SI+4], 0Fh |