Недокументированные возможности MS-DOS - Прерывания 30h и 31h
Прерывания 30h и 31h не используются в DOS и о них ничего не говорится в обычных руководствах программиста по DOS. Строго говоря, их вообще нельзя назвать прерываниями и тем более пытаться их выполнить. Ни к чему хорошему это не приведет, поскольку ячейки памяти, зарезервированные для векторов этих двух прерываний (0:00C0 - 0:00C7) не содержат, как обычно, адресов процедур, выполняющих обработку прерываний.
Вместо зтого, начиная с адреса 0:00C0 (адрес вектора прерывания 30h) располагается команда JMP FAR seg:off, которая указывает на альтернативный обработчик прерывания 21h. В результате, зная правила передачи параметров и и другой необходимой для обработчика прерывания информации, можно осуществить прямой доступ в DOS, не генерируя прерывание 21h, а просто выполняя переход на описанную команду.
Естественно, зтот способ позволяет получить доступ только к оригинальному обработчику прерывания 21h. И если программой был установлен другой обработчик этого прерывания, управление указанным способом ему передано не будет. Во многих случаях зто, конечно, очень удобно. Однако нельзя забывать, что это еще более удобно для вирусов, желающих, чтобы их обращения к функциям DOS осталось незамеченным.
Своим существованием эта команда обязана желанию разработчиков PC-DOS и MS-DOS обеспечить совместимость с операционной системой CP/M, где для вызова функции DOS было необходимо выполнить команду CALL 0005, предварительно загрузив номер функции в регистр CL. Этот вызов выполнял команду, находяшуюся по смещению 5 в PSP, а та, в свою очередь, вызывала DOS.
Описанный способ доступа к DOS существует в PC-DOS, начиная с версии 1.1, и в большинстве версий MS-DOS.
;---------------------------------------------------------------------------- ; Пример вызова функции 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, "$"