НЕДОКУМЕНТИРОВАННЫЕ СТРУКТУРЫ MS-DOS И ИХ ИСПОЛЬЗОВАНИЕ.

Кондратюк Д.С., Чередникова О.Ю.
Компьютерный мониторинг и информационные технологии. Материалы III международной научно-технической конференции студентов, аспирантов и молодых ученых. — Донецк, ДонНТУ — 2007.
Донецкий национальный технический университет, г. Донецк

Управлением ресурсами ЭВМ и обеспечением их взаимодействия с окружающей средой занимаются операционные системы (ОС). В наше время существует много популярных операционных систем(UNIX, BeOS, Windows 95/98/NT/XP/CE/Vista, OS/2,QNX и др.) которые используются в соответствующих их назначению контекстах. Многие операционные системы в области «домашнего» рынка оказались на грани вымирания в связи с ограничением предоставляемых ими возможностей для организации мультимедиа и многозадачности. Но основным их достоинством до сих пор остаётся простота, малая требовательность к ресурсам и отсутствие ограничений на их использование (к примеру, для таких систем необязательна поддержка Protected Mode процессором, для нормальной работы им хватает совместимости с большинством спецификаций IBM PC). В связи с этим поддержка таких систем продолжается, и выпускаются их новые версии, которые в основном отличаются от предыдущих драйверами новых устройств. Следовательно, в этой области упор делается на системное программирование и сопряжение компьютера с нестандартными внешними устройствами.

Также следует отметить, что ядро DOS, Unix в измененном (приспособленном, усеченном) виде лежит в основе многих современных операционных систем. И хотя знание ДОС не требуется для понимание их работы, знакомство со структурой и идеей функционирования его ядра даёт возможность сравнить и глубже понять принципы работы современных систем и, что намного важнее, определить тенденции и альтернативы их развития (в особенности это касается развития процессорных систем, расширения предлагаемых ими функций и режимов многозадачности, защиты).

Взаимодействие MS-DOS с окружающей средой обеспечивают резидентные программы (драйверы и другие резиденты, оставленные в памяти по завершении их программы-носителя), которые тем или иным образом перехватывают прерывания (например, драйверы вызываются самой системой). Драйверы – это особые резиденты, которые загружаются в память вместе с системой. MS-DOS 3.0+ позволяет работать с драйверами как с обычными файлами. Механизм же самой этой работы скрыт от программиста. Как следствие многие функции и приемы для работы с ними являются недокументированными, и их правильная работа не гарантируется.

Для того чтобы продемонстрировать, как на глубоком уровне работают функции расширенной версии ДОС, была написана специальная программа. Она переключает драйвер консоли. Отличительной возможностью данной программы (по сравнению с другими аналогами) является локальное переключение драйвера консоли (заменяющий/стандартный) для текущего процесса.

Идея программы состоит в том, что для переключения используется не прямое изменение внутренних системных таблиц ДОС (структурной составляющей), а обращение к её функциям (механической составляющей), что, по сути, является внешним тестированием недокументированных возможностей сервиса ДОС.

Для того чтобы целостно понять принцип работы программы можно рассмотреть её взаимодействие (обратную связь) с ДОС с двух точек зрения: программы и ядра.

С точки зрения программы, она удалила заменяющий драйвер консоли из цепочки драйверов, и, чтобы изменения (для неё) вступили в силу, переоткрыла всю консоль. В результате программа получила свой личный доступ к стандартному драйверу. Преимуществом данного подхода является также то, что для резидентов, которые в данный момент находились в памяти, ничего не изменится. Они также как и раньше обращаются к заменяющему драйверу. Это свойство очень полезно для отладки ненадёжных драйверов, особенно тех, которые могут неожиданно вызваться по прерыванию таймера.

С точки зрения ДОС к ней сначала присылается запрос на закрытие дескрипторов 0,1,2 используемых консолью, а затем просят открыть консоль в режиме чтения, записи. Для того чтобы понять, что ДОС делает с этими запросами, рассмотрим механизм её работы с файлами.

Информацию об открытых файлах и устройствах система хранит в таблице SFT(для прерываний в режиме V86 под Windows используется усеченная версия SFT – не все данные в ней корректны, т.к. информацию об открытых файлах Windows хранит в собственных структурах). Каждое новое открытие файла создаёт новое вхождение и PSP программы его открывшей заносится в поле хозяина. Это поле используется в основном для удаления вхождений при завершении программы. Чтобы определить какая программа посылает сервису запрос на ввод/вывод и какие вхождения ей нужны ОС создаёт в PSP программы структуру JFT(рабочая таблица файлов) в которой номера дескрипторов сопоставлены номерам вхождений в SFT. Ссылку на неё ДОС размещает также в PSP.

При открытии файлов/устройств программой ДОС ищет их сначала в цепочке драйверов, а потом в соответствии с переменными окружения программы. Затем создаёт для каждого отдельный дескриптор, который будет сопоставлен новому вхождению. В случае с нашей программой при попытке открытия ОС находит стандартный драйвер (т.к. замещающий был из цепочки удален) а затем определяет для него дескриптор в JFT. За счет того, что перед открытием стандартные дескрипторы были закрыты, ДОС записывает номер вхождения в первые байты JFT.

При вызове расширенных функций ДОС с запросами на работу с консолью, они определяют (по адресу возврата в стеке) PSP программы их вызвавшей. Затем находят по JFT(она для каждой программы своя) номер вхождения и в соответствии с полем DCB(Device Control Block, заголовок устройства) используют нужную программу-драйвер. Причем все обращения к вхождению ДОС фиксирует в поле FilePos, увеличивая его.

В результате, даже если произошла непосредственная подмена драйвера в SFT, программа продолжает работать со старым драйвером. К тому же несложно изменять значения непосредственно в JFT или просто её переключать. Таким образом, появляется возможность создавать тесты, которые могут сравнивать эталонный драйвер с тестируемым, не давая системе обнаружить его (тестируемый драйвер не обязательно загружать вместе с системой, можно просто выделить для него блок памяти и добавить в цепочку перед закрытием-открытием, затем – удалить). Также появляется возможность назначать любой резидентной программе в памяти (если она взаимодействует с драйвером по Handle-принципу) любой драйвер по имени процесса (процесс всегда можно найти по MCB).

Разработанная программа является одним из возможных примеров того, как можно решать различные задачи системного характера в среде MS-DOS 3.0+. Знание и практическое использование недокументированных структур позволяет решать нестандартные задачи на ЭВМ, а также дает представление о внутренних принципах работы 16-разрядных ОС.