Мне известны следующие способы организации доступа к портам I/O в NT/2k/XP/2003: 1) Модификация I/O Permission Map (IOPM). Используются недокументированные функции Ke386IoSetAccessProcess, Ke386SetIoAccessMap, Ke386QueryIoAccessMap. Классический пример - драйвер gwiopm. 2) Модификация IOPL (I/O Privilege Level) с помощью недокументированного вызова API NtSetInformationProcess(..., ProcessUserModeIOPM, ...). Пример присутствует на этом форуме. 3) Выполнение участков кода в Ring-0 путем организации callgate (через \Device\PhysicalMemory). Пример, опять-таки, присутствует на этом форуме. Все вышеперечисленные методы имеют один критический недостаток - использование недокументированных вызовов/структур и т.п. Соответственно, переносимость между версиями ОС (например, переход с 2k на XP) никем и ничем не гарантирована. Более того, их выполнение требует весьма высокого уровня привилегий (1 & 3 - Administrator, 2 - вообще Local System, т.к. привилегия SE_TCB_NAME ("Act As Part of the Operating System") по дефолту отсутствует даже у администратора) - так что проще драйвер загрузить. IMHO, область применения таких "трюков" - чистый proof of concept (спикером попищать . Степень практической полезности этих трюков уменьшается еще и от того, что Microsoft предусмотрела легальный и прекрасно документированный метод доступа к портам I/O - написание драйверов устройств В DDK даже пример готовый есть, откомментированный "от и до" (.\src\general\portio\). Навскидку я могу вспомнить только один случай, когда шел разговор об использовании одного из этих методов на практике - перенос изначально КРИВО написанной программы с Win9x на WinNT (при отсутствии исходных текстов, разумеется). Задачу удалось решить строго в рамках документированных средств, написав маленький отладчик, реагирующий на EXCEPTION_PRIV_INSTRUCTION и вызывающий драйвер для выполнения ввода-вывода (единственная проблема такого метода - низкая скорость). PS. 2 Quantum, Авг 23, 2005 18:41:10 Неверно. Попробуйте обратиться, например, к портам контроллера HDD. Или посмотрите 9x DDK на предмет I/O Trapping. Другое дело, что в 9x возможна модификация IOPM из ring-3 (десяток строчек на asm).
alpet Это не любопытства!!! Я должен создать пример на DELPHI который обращается к портам I/O без драйвера за это я получу дипломку... да ещё и деньги...
ABC Вот видишь, определенные мотивы есть к изучению вопроса. Но всеже замечу сразу, для обращения к I\O без дравера нужно приготовится к проблемам с программой, даже пускай она писк выдает. Может потом у тебя потребуют, чтобы она из под гостя могла также работать, иначе никаких денег. Лучше найди себе задачу под диплом, с эффектом реального и рационального применения, которую можешь решить сам.
Skif Я под запущенной Win98 форматировал винт, программой реального режима, просто восстанавливал реальный вектор int 13, и использовал его. Стало быть защита не такая уж и серьезная.
Quantum, alpet Возможно, я немного неточно сформулировал свою реплику, попробую исправиться В моем случае речь шла о доступе к портам I/O из обычного ring-3 win32-приложения. Win9x свободно разрешает доступ к определенным портам (в частности, CMOS), но, к примеру, попытки обратиться к портам контроллера HDD успехом не увенчаются (GP Fault не возникает, но и в порты ничего не пишется). В Win9x существует механизм I/O Trapping (перехват обращений к портам I/O, подробно описанный в 9x DDK), действующий, как оказалось, в том числе и для win32 приложений (в линейке NT подобный механизм работает только для NTVDM-приложений, см. NT DDK на предмет VDD - Virtual Device Drivers). Этот механизм основан на манипуляции с IOPM (I/O Permission Map, см. документацию i386+ на предмет TSS), и если в NT для win32 (IOPL-3, вернее) приложений закрыт доступ ко всем портам, то в 9x есть нюансы. Содержимое IOPM в Win9x можно посмотреть в SoftICE (см. документацию, команда tss). Так вот, один из драйверов дисковой подсистемы 9x перехватывает обращение к портам контроллера HDD. Однако, в 9x корректировать IOPM можно прямо из ring-3 кода (в NT требуется применение недокументированных ф-ций Ke386IoSetAccessProcess, Ke386SetIoAccessMap, Ke386QueryIoAccessMap), что сводит такую защиту на нет. Ниже приведен фрагмент кода, разрешающий доступ к портам 1-го контроллера HDD. Код (Text): ;Сохраняем адрес GDT sub esp,6 sgdt [esp] add esp,2 pop ebx ;Селектор TSS -> ESI, сбрасываем TI & PL str si and esi,0FFF8h ;Базовый адрес TSS -> EAX mov ah,[ebx+esi+7] mov al,[ebx+esi+4] shl eax,16 mov ax,[ebx+esi+2] ;Смещение IOPM от начала TSS add ax,word ptr [eax+66h] ;Разрешаем доступ к портам 0x1f0..0x1f7 mov byte ptr [eax+1F0h/8], 0 PS. Написано немного сумбурно из-за недостатка времени. Если в голову придет что-то получше, пост поправлю.
Исполнение инструкций IN\OUT возможно из нулевого кольца, или редактированием соответствующей карты I\O. Переход с режыма пользователя в режим ядра на платформе Intel возможен двумя механизмами: прериваниями и через "Шлюз вызова"(зубная паста CallGate). Как насчёт \Device\PhysicalMemory и зубной пасты?
\Device\PhysicalMemory - это объект ядра, обладающий своим собственным SD (Security Descriptor), и вовсе не обязательно, что доступ к нему с соответствующими permissions разрешен даже для Administrators (см. например Integrity Protection Driver, есть и другие подобные средства). Более того, судя по слухам, в 2k3 доступ к \PhysicalMemory перекрыт даже на чтение средствами самой ОС (по крайней мере, hkit от z0mbie в 2k3 не работает (NTSTATUS -> 0xc0000018), хотя в 2000 все работает). Есть мнение, что прибегать к недокументированным средствам имеет смысл только тогда, когда других вариантов уже не осталось. А в NT есть законный и прекрасно документированный метод "перехода в ring-0" - драйвер устройства.
Skif Я не понял тогда, а почему у меня винт форматировался (функция ah = 05h), при использовании оригинального обработчика int 13 из BIOS-ROM? Или такая несерьезная операция не требует обращений к портам HDD (у меня тогда был Seagate 420Mb)? Сказать по правде процесс такого "форматирования", не всегда доходил до конца (забивание секторов диска значениями 0xF6), и иногда вылазил BSOD.
alpet Требует, разумеется. Но архитектура 9x представляет собой гремучую смесь из кода защищенного и реального режимов (подробнее см. Matt Pietrek, Windows 95 System Programming), с весьма условными проверками на возможность выполнения тех или иных действий разными частями системы. Именно поэтому в ней возможны манипуляции навроде вызова оригинального обработчика int 13 и т.п. Ну и куча глюков, разумеется.
Quantum да ты что говоришь ))) внимательно посмотри на карту iopm, к винту к примеру ты хрен доступ получишь, к сетевухе так же, остальное не помню, трапит он порты частично !
Только недавно появилась возможность выходить в нет. Очень понравился этот форум. Вижу столько вкусного... Однажды пришлось решать проблему работы с портами ввода/вывода напрямую через IN/OUT. Бесспорно можно было бы написать legacy дррайвер, но хотелось по-русски по простому, без перехода в ring0. И как-то в книге Гарри Небета попалось мне описание недокументированной функции ZwSetProcessInformation. Грыз, я её грыз, и через какое-то время понял, что необходим еще и доступ администратора для установки привилегии SE_TCB, и SEH-обработчик исключения 0xc0000096 (привилегированная инструкция). В конце концов родил я програмулину которая в простейшем диалоговом окне считывает из любого порта,записывает в порт, на ручном управлении, а также позволяет выбрать любой *.EXE файл разрешить ему IOPL=3 как бы также обращатся к портам ввода/вывода, и библиотечку при вызове которой, вызывающему процессу так же повышается привелегия ввода/вывода до 3.Так вот какой вопрос у меня, почему привилигерованная программа которая может общатся с портами ввода/вывода в ring3, выполнять другие привилигерованные инструкции процессора, чувствительные к уровню IOPL, например sgdt и т.д. Не может выполнить смертельную инструкцию ldt. Кто нибудь может мне обьяснить. спасибо.
К уровню IOPL чувствительны только инструкции in и out. sgdt может выполняться при любом CPL и IOPL, а lidt только при CPL = 0, а к уровню IOPL не чувствительна. Для использования этой инструкции тебе обязательно придется в ринг0 лезть.
Понял, спасибо Ms Rem. На программе попробовал, так и есть. А например такие инструкции как cli,sti они чувствительны к уровню? Вроде из программы выполняются...
Вообще-то гораздо большее количество команд. cli, sti, insX, outsX, in, out, popfd, iretd (IOPL учитывается при попытке модификации IF),...