|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Листинг 5.7. Код, осуществляющий чтение сектора с диска в режиме LBAMOV 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, выполняется обыкновенная запись по умолчанию. Теперь, освоившись с дисковыми прерываниями, перейдем к обсуждению остальных аспектов программирования. Создаем код загрузчика Лучше всего загрузчики программируются на FASM. С точки зрения ассемблера загрузчик представляет собой обыкновенный двоичный файл, предельно допустимый объем которого составляет 1BBh (443) байт. Немного? Но не будем спешить с выводами. Всякий раздел всегда начинается с начала цилиндра, а это значит, что между концом MBR и началом раздела имеется, по меньшей мере, n свободных секторов, где n == sectors per track. Практически все современные винчестеры имеют по 64 сектора на дорожку, что дает нам: 443 + 63*512 == 32 699 байт или приблизительно 32 Кбайт. Да в этот объем даже графический интерфейс с мышью уместить можно! Однако делать этого мы не будем. Настоящие хакеры работают в текстовом режиме с командной строкой. Как уже говорилось, BIOS загружает MBR по адресу 7C00h, поэтому в начале ассемблерного кода должна стоять директива ORG 7C00h, а еще — USE16, ведь загрузчик выполняется в 16-разрядном реальном режиме. Позже, при желании, он может перейти в защищенный режим, но это будет уже потом. Не будем лезть в такие дебри. Обнаружив загрузочный раздел (а обнаружить это можно по флагу 80h, находящемуся по нулевому смещению от начала раздела), загрузчик должен считать первый сектор этого раздела, поместив его в памяти по адресу 0000:7C00h, то есть в точности поверх своего собственного тела. А вот это уже нехорошо! И чтобы не вызвать крах системы, загрузчик должен заблаговременно перенести свое тело по другому адресу, что обычно осуществляется командой MOVSB. Копироваться можно по любому из адресов памяти — от 0080:0067h до 9FE00h. Память, расположенную ниже 0080:0067h, лучше не трогать, так как здесь находятся вектора прерываний и системные переменные BIOS, а от A000h и выше начинается область отображения ПЗУ, так что предельно доступный адрес равен A000h - 200h (размер сектора) == 9FE00h. Не забывайте, что трогать регистр DL ни в коем случае нельзя, поскольку в нем передается номер загрузочного привода. Некоторые загрузчики содержат ошибку, всегда загружаясь с первого жесткого диска, и это в то время, как BIOS уже больше 10 лет как позволяют менять порядок загрузки, и потому загрузочным может быть любой привод. По правде говоря, FASM — это единственный известный мне ассемблер, "переваривающий" команду дальнего вызова JMP 0000:7C00h напрямую. Все остальные ассемблеры заставляют извращаться приблизительно так: PUSH offset_of_target/PUSH segment_of_target/RETF. Здесь мы заталкиваем в стек сегмент и смещение целевого адреса и выполняем дальний RETF, переносящий нас на нужное место. Еще можно воспользоваться самомодифицирующимся кодом, собрав команду JMP FAR "вручную", или просто расположить целевой адрес в одном сегменте с исходным адресом (например, 0000:7C00h → 0000:7E00h). Однако эти подходы муторны и утомительны. В общем, скелет нашего загрузчика будет выглядеть так, как показано в листинге 5.8. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.) |