АЛЬТЕРНАТИВНЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ INT 21h Альтернативный обработчик прерывания 21h предъявляет дру- гие требования к входным параметрам, чем обычный вызов INT 21h. Его использование требует некоторых специальных действий и понима- ния того, что он позволяет. Прежде всего, обработчик ожидает, что адрес возврата будет в стеке в отличном от обычного порядке. Обычно, когда генерируется прерывание, процессор сначала заносит в стек флаги, а затем сег- мент и смещение адреса возврата. Однако в этой точке входа предпо- лагается, что флаги были занесены в стек последними, после занесе- ния смещения и сегмента адреса возврата. Назначение команд, находящихся в этой точке входа - выпол- нить некоторую предварительную обработку входных данных и стека, прежде чем передать управление стандартному обработчику прерывания 21h. Иными словами, альтернативный обработчик прерывания является лишь надстройкой над стандартным. Поэтому первое, что он делает - это перестраивает стек в стандартном порядке, приемлемом для ко- манды IRET. Следующим действием альтернативный обработчик прерывания 21h контролирует номер запрашиваемой для выполнения функции и до- пускает только функции с номерами 00h-24h. Поскольку регистр AX разрушается сразу же после входа, номер функции передается в ре- гистре CL, а не в AH. Это же означает, что даже среди допустимых функций есть недоступные: те, которые требуют дополнительного па- раметра в регистре AL. Так, например, недоступна функция 0Ch (очистить буфер клавиатуры и затем вызвать одну из функций 01h, 06h, 07h, 08h, или 0Ah), поскольку она требует номер подфункции в регистре AL. Однако как узнать, где располагается этот обработчик пре- рывания, чтобы получить к нему доступ? Вектор прерывания 30h со- держит команду JMP FAR, позволяющую перейти по требуемому адресу. Таким образом, чтобы использовать прямой вызов DOS, вызывающая программа должна занести в стек сначала флаги, затем смещение и сегмент адреса возврата, а потом загрузить в регистр CL номер фун- кции и выполнить далекий переход по адресу 0:00C0, передав таким образом управление альтернативному обработчику прерывания 21h. По окончании функционирования обработчик прерывания 21h выполняет ко- манду IRET по адресу возврата, находящемуся, как обычно, в стеке. Остается выяснить вопрос: для чего вообще нужен альтерна- тивный обработчик прерывания 21h, почему к нему такой необычный способ доступа и отчего в нем такое странное соглашение о входных параметрах. На все эти три вопроса можно ответить одновременно: это связано с желанием разработчиков MS-DOS обеспечить совмести- мость с операционной системой CP/M, господствовавшей до появления MS-DOS. Поэтому соглашение о входных параметрах и ограниченность выбора функций, столь странные для пользователей MS-DOS, отнюдь не покажутся странными тем, кто еще помнит CP/M. А что же касается необычного способа доступа к альтернативному обработчику прерыва- ния, то описанный способ в действительности не используется, хотя он вполне корректен, а команда JMP FAR в векторе прерывания 30h существует исключительно для поддержки вызова функций DOS в стиле CP/M через PSP: командой CALL 0005. Описанный альтернативный обработчик прерывания 21h сущест- вует во всех версиях PC-DOS и почти во всех версиях MS-DOS. Инте- ресно заметить, что код этого обработчика, судя по проведенным ис- следованиям, одинаков во всех версиях DOS и, следовательно, имеет одну и ту же длину. Очевидно, что он является не более чем руди- ментом, оставшимся в наследство от операционной системы CP/M, эта- кий аппендикс MS-DOS. Далее, сегмент DOS, где располагаются все его функции, можно получить многими способами, а смещение в нем альтернативного обработчика прерывания 21h, как, следовательно, и стандартного, одинаково в пределах одной версии DOS, пусть даже и разных фирм. Можно, конечно, и обойти существующее в этой точке входа ограничение на номер функции. Для этого нужно просто затереть ко- мандами NOP проверку на допустимость номера. При этом нельзя упус- кать из виду другое ограничение: нельзя пользоваться функциями, требующими параметров в регистрах AL и CL. ;---------------------------------------------------------------------------- ; Листинг (срез) альтернативного обработчика прерывания 21h. ; Текст немного упрощен для лучшей читабельности при ; сохранении полной смысловой идентичности. ;---------------------------------------------------------------------------- RefuseRequest: ; Отказ от выполнения запрашиваемой функции, mov ax, 0 ; т.к. номер функции недопустим. iret Alt_DOS_Entry: ; Точка входа в альтернативный обработчик прерывания pop ax ; Извлечь из стека содержимое регистра флагов pop ax ; Извлечь из стека сегмент адреса возврата pop cs:Temp ; Извлечь из стека смещение адреса возврата ; Перестроить стек для команды IRET pushf ; Сохранить в стеке флаги cli ; Запретить генерацию прерывания 21h push ax ; Сохранить сегмент адреса возврата push cs:Temp ; Сохранить смещение адреса возврата cmp cl, 24h ; Номер функции меньше максимального? ja RefuseRequest ; Нет. Отказ обрабатывать запрос. ; Допустимый номер функции. mov ah, cl ; Загружаем номер функции в AH и переходим jmp short INT_21h_Further ; в стандартный обработчик INT 21h INT_21h_Entry: ; Стандартный обработчик прерывания 21h cmp ah, 6Ch ; Номер функции меньше максимального? ja RefuseRequest ; Нет. Отказ обрабатывать запрос. ; Допустимый номер функции. INT_21h_Further: cmp ah, 51h . . . . . . ;---------------------------------------------------------------------------- ;---------------------------------------------------------------------------- ; Пример вызова функции DOS через альтернативный обработчик ; прерывания 21h. ;---------------------------------------------------------------------------- mov ax, offset RETURN ; Взять смещение адреса возврата push ax ; Занести в стек флаги, сегмент push cs ; и смещение адреса возврата pushf ; в обратном порядке. mov cl, 9 ; Функция: показать строку. mov dx, offset MESSAGE ; Загрузить адрес сообщения. push cs ; Для уверенности, что DS pop ds ; указывает на текущий код. jmp dword ptr ALT_DOS_PTR ; Выполнить функцию. RETURN: mov ah, 4Ch ; Завершить процесс через DOS. int 21h ; ALT_DOS_PTR dw 00C0h, 0000 ; Адрес для перехода в альтер- ; нативный обработчик MESSAGE db 0Dh, 0Ah, "Example of backdoor MS-DOS " db "function call.", 0Dh, 0Ah, 7, "$" ;----------------------------------------------------------------------------- Алексей Баулин (PEGASUS Software). 150000, г.Ярославль, ул.Б.Октябрьская, д.63/3, кв.29 телефоны: (085-2) 25-49-53 (раб) (085-2) 22-51-05 (дом)