Вызов шлюза (Intel)
Эта статья нуждается в дополнительных цитатах для проверки . ( август 2020 г. ) |
Шлюз вызова — это механизм в архитектуре Intel x86 для изменения уровня привилегий процесса, когда он выполняет вызов предопределенной функции с помощью инструкции CALL FAR.
Обзор
[ редактировать ]Шлюзы вызова предназначены для того, чтобы позволить менее привилегированному коду вызывать код с более высоким уровнем привилегий. Этот тип механизма важен в современных операционных системах, использующих защиту памяти , поскольку он позволяет пользовательским приложениям использовать функции ядра и системные вызовы таким образом, чтобы операционная система могла контролировать их .
Шлюзы вызова используют специальное значение селектора для ссылки на дескриптор, доступ к которому осуществляется через глобальную таблицу дескрипторов или локальную таблицу дескрипторов , которая содержит информацию, необходимую для вызова через границы привилегий. Это похоже на механизм, используемый для прерываний .
Использование
[ редактировать ]Предполагая, что шлюз вызова уже настроен операционной системы ядром , код просто выполняет CALL FAR с необходимым селектором сегмента (поле смещения игнорируется). Процессор выполнит ряд проверок, чтобы убедиться, что запись действительна и код работает с достаточными привилегиями для использования шлюза. Предполагая, что все проверки пройдены, новый CS/ EIP загружается из дескриптора сегмента , а информация о продолжении помещается в стек нового уровня привилегий (старый SS, старый ESP, старый CS, старый EIP, именно в этом порядке). При необходимости параметры также можно скопировать из старого стека в новый стек. Количество копируемых параметров указано в дескрипторе шлюза вызова.
Ядро может вернуться в программу пользовательского пространства, используя инструкцию RET FAR, которая извлекает информацию о продолжении из стека и возвращается на внешний уровень привилегий.
Формат дескриптора шлюза вызова
[ редактировать ]typedef struct _CALL_GATE
{
USHORT OffsetLow;
USHORT Selector;
UCHAR NumberOfArguments:5;
UCHAR Reserved:3;
UCHAR Type:5; // 01100 in i386, 00100 in i286
UCHAR Dpl:2;
UCHAR Present:1;
USHORT OffsetHigh;
}CALL_GATE,*PCALL_GATE;
Предыдущее использование
[ редактировать ]Multics был первым пользователем шлюзов вызова. Honeywell 6180 имел шлюзы вызова как часть архитектуры, но Multics смоделировала их на более старом GE 645 .
OS/2 была одним из первых пользователей шлюзов вызовов Intel для передачи между кодом приложения, работающим в кольце 3, привилегированным кодом, выполняющимся в кольце 2, и кодом ядра в кольце 0.
Windows 95 выполняет драйверы и переключение процессов в кольце 0, в то время как приложения, включая API DLL, такие как kernel32.dll и krnl386.exe, выполняются в кольце 3. Драйвер VWIN32.VXD предоставляет ключевые примитивы операционной системы в кольце 0. Он позволяет вызывать драйвер. функции из 16-битных приложений (MSDOS и Win16). Этот адрес получается путем вызова INT 2Fh с значением 1684h в регистре AX. Чтобы определить, какой VxD запрашивается точка входа, в регистре BX устанавливается 16-битный идентификатор VxD. После возврата из инструкции INT регистры ES.DI содержат дальний указатель, который можно вызвать для передачи управления VxD, работающему в кольце 0. Дескриптор, на который указывает ES, на самом деле является шлюзом вызова. [1] Однако 32-битные приложения, когда им требуется доступ к коду драйвера Windows 95, вызывают недокументированную функцию VxDCall в KERNEL32.DLL, которая по сути вызывает INT 30h, что изменяет режим звонка.
Современное использование
[ редактировать ]Современные операционные системы x86 переходят от шлюзов вызовов CALL FAR. С появлением инструкций x86 для системных вызовов (SYSENTER/SYSEXIT от Intel и SYSCALL/SYSRET от AMD) был введен новый более быстрый механизм передачи управления для программ x86. Поскольку большинство других архитектур не поддерживают шлюзы вызовов, их использование было редким даже до появления этих новых инструкций, поскольку программные прерывания или ловушки были предпочтительными для переносимости, хотя шлюзы вызовов работают значительно быстрее, чем прерывания.
Шлюзы вызовов более гибкие, чем инструкции SYSENTER/SYSEXIT и SYSCALL/SYSRET, поскольку, в отличие от последних двух, шлюзы вызовов позволяют переходить от произвольного уровня привилегий к произвольному (хотя и более высокому или равному) уровню привилегий. Быстрые инструкции SYS* позволяют передавать управление только с кольца 3 на кольцо 0 и наоборот.
Проблемы безопасности
[ редактировать ]Чтобы сохранить безопасность системы, глобальная таблица дескрипторов должна храниться в защищенной памяти, иначе любая программа сможет создать свой собственный шлюз вызова и использовать его для повышения своего уровня привилегий. Шлюзы вызова использовались в эксплойтах безопасности программного обеспечения , когда были найдены способы обойти эту защиту. [2] Одним из примеров является почтовый червь Gurong.A , написанный для эксплуатации операционной системы Microsoft Windows , которая использует \Device\PhysicalMemory для установки шлюза вызова. [3]
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Мэтт Питрек , Секреты системного программирования Windows 95
- ^ по повышению привилегий Intel SYSRET Блог проекта Xen
- ^ Червь: W32/Gurong.A Описание F-Secure Labs