Подтвердить что ты не робот

Как Windows защищает переход в режим ядра?

Как Windows защищает от потока пользовательского режима от произвольного перехода процессора в режим ядра?

Я понимаю, что это правда:

  • Потоки пользовательского режима действительно переходят в режим ядра, когда системный вызов выполняется через NTDLL.
  • Переход в режим ядра осуществляется с помощью инструкций, специфичных для процессора.

Итак, что особенного в этих системных вызовах через NTDLL? Почему поток пользовательского режима не может подделать и выполнять инструкции, специфичные для процессора, для перехода в режим ядра? Я знаю, что здесь отсутствует какая-то ключевая часть архитектуры Windows... что это такое?

4b9b3361

Ответ 1

Вероятно, вы думаете, что поток, запущенный в пользовательском режиме, вызывает Ring 0, но это не то, что на самом деле происходит. Поток пользовательского режима вызывает исключение, которое попадает в код Ring 0. Поток пользовательского режима останавливается, и CPU переключается на поток ядра/кольца 0, который затем может проверять контекст (например, стек вызовов и регистры) потока пользовательского режима, чтобы выяснить, что делать. Перед syscall это действительно было исключение, а не специальное исключение специально для вызова кода кольца 0.

Если вы ответите на другие ответы и прочитайте руководства Intel, вы увидите, что syscall/sysenter не принимает никаких параметры - ОС решает, что происходит. Вы не можете вызвать произвольный код. WinNT использует номера функций, которые отображают, к какой функции режима ядра выполняется код пользовательского режима (например, NtOpenFile - fnc 75h на моей машине Windows XP (числа меняются все время; одно из заданий NTDll - это отображение вызов функции к номеру fnc, поместите его в EAX, укажите EDX на входящие параметры, затем вызовите sysenter).

Ответ 2

Процессоры Intel обеспечивают безопасность, используя так называемые "Защитные кольца".

Есть 4 из них, пронумерованных от 0 до 3. Код, выполняющийся в кольце 0, имеет самые высокие привилегии; он может (практически) делать все, что угодно с вашим компьютером. Код в кольце 3, с другой стороны, всегда находится на жестком поводке; он имеет ограниченные полномочия влиять на вещи. И кольца 1 и 2 в настоящее время не используются для каких-либо целей.

Поток, выполняющийся в более высокоприоритетном кольце (например, кольцо 0), может переходить к нижнему кольцу привилегий (например, кольцу 1, 2 или 3) по желанию. Тем не менее, переход по-другому строго регламентирован. Так обеспечивается безопасность высокоприоритетных ресурсов (таких как память) и т.д.

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

Подробнее о том, как все это реализовано, можно прочитать эту статью. Кроме того, вы также можете ознакомиться с руководствами Intel, особенно с Vol 1 и Vol 3A, которые вы можете скачать здесь .

Это история для процессоров Intel. Я уверен, что в других архитектурах есть что-то подобное.

Ответ 3

Я думаю (возможно, ошибаюсь), что механизм, который он использует для перехода, прост:

  • Код пользовательского режима выполняет программное прерывание.
  • Это (прерывание) вызывает ветвь в местоположении, указанном в таблице дескриптора прерываний (IDT)

То, что мешает коду пользовательского режима узурпировать это, заключается в следующем: вам нужно быть привилегированным для записи в IDT; поэтому только ядро ​​может указать, что происходит, когда выполняется прерывание.

Ответ 4

Код, выполняющийся в пользовательском режиме (Ring 3), не может произвольно переключиться в режим ядра (Ring 0). Это можно сделать только с помощью специальных маршрутов - переходов, переходов и векторов sysenter. Эти маршруты очень защищены, а ввод очищается, поэтому плохие данные не могут (не должны) вызывать плохое поведение.

Все это устанавливается ядром, обычно при запуске. Он может быть настроен только в режиме ядра, поэтому код пользовательского режима не может его изменить.

Ответ 5

Возможно, справедливо сказать, что он делает это (относительно) аналогично тому, что делает Linux. В обоих случаях это будет специфичным для процессора, но на x86 возможно либо прерывание программного обеспечения с инструкцией INT, либо с помощью команды SYSENTER.

Преимущество в том, как Linux делает это, что вы можете сделать это без исходной лицензии Windows.

часть источника пользовательского пространства здесь здесь в LXR и бит пространства ядра - посмотрите на entry_32.S и entry_64.S

В Linux на x86 существуют три разных механизма: int 0x80, syscall и sysenter.

Библиотека, которая построена во время выполнения ядром под названием vdso, вызывается библиотекой C для реализации функции syscall, которая использует другой механизм в зависимости от процессора и какой системы его зовут. Затем у ядра есть обработчики для этих механизмов (если они существуют в конкретном варианте ЦП).