Поясните пожалуйста насчет колец защиты

Тема в разделе "WASM.OS.DEVEL", создана пользователем _220, 16 апр 2007.

  1. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Mika0x65,

    ну не знаю, когда я изучал PM по Финогенову, я такого не видел. Для демок которые только в 0-м кольце работают такого точно не нужно, а чтобы перейти на другое кольцо.. Вот (по Зубкову С.В.):

    Селектор — это 16-битное число следующего формата:

    биты 16 – 3: номер дескриптора в таблице (от 0 до 8191)

    бит 2: 1 — использовать LDT, 0 — использовать GDT

    биты 1 – 0: запрашиваемый уровень привилегий при обращении к сегменту и текущий уровень привилегий для селектора, загруженного в CS

    Вот селектора в 98:

    ----- kernel --------
    28h (code) биты: 000
    30h (data) биты: 000
    ----- app32 --------
    cs:167h (code) биты: 111
    ss:016F (data/stack) биты: 111
    fs:395F: биты: 111

    Итого всюду уровень 3 или 0, для уровня 0 используецца LDT. Разве недостаточно сделать retf в ядре для перехода в 3-е кольцо?
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    ++

    Да, именно так. Вот как делаецца переход в ядро в 98 и обратно (trace of GetLocalTime):

    kernel32: call far [...]
    kernel32: int 30h ; to VMM core

    VMM: call [Exec_PM_Int]
    VMM: iretd ; ss:esp -> C5,12,F7,BF,67,01

    kernel32: 0167:BFF712C5 ; We've returned here from VMM

    Так что достаточна iretd.
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    ну если в стеке лежат последовательно SS3, ESP3, CS3, EIP3 и CPL = 0 тогда да
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Для возврата действительно достаточно посместить в стек указатели, как сказал rei3er. Но, например, при прерывании или использовании шлюза вызова, когда происходит смена уровней привилегий требуется также сменить уровень привилегий стека (это одно из требований процессора, чтобы уровень привилегий стека всегда соответствовал уровню привилегий кода) -- в этом случае как раз и требуется TSS: в нем хранятся указатели стека (SS0:ESP, SS1:ESP, SS2:ESP), для разных уровней привилегий задачи.
     
  5. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Хм, а кто мешает тупо записать в дескриптор адрес своего обработчика. Может сечас что-то поменялось, смотреть лень,
    но на старых процах при записи в дескриптор int1, если на нем стоял
    брекпойнт на запись, вызов обработчика происходил по модифицированному адресу. Думаю, что и на нынешних процах так же.
    З.Ы. Как вариант - создать свою IDT. По крайней мере для борьбы с
    SF я так делал.
     
  6. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Хм, да, в 98 есть TSS:

    ltr ax ;-> 18h
    gdt 18 ; -> sel:18h, Type:TSS32, Base:C000D7A4h, Lim:2069h, DPL:0...

    А вот что у нас в самой TSS (описание по Зубкову С.В.):

    TSS имеет следующую структуру:

    +00h: 4 байта — селектор предыдущей задачи (старшее слово содержит нули — здесь и для всех остальных селекторов)

    -> 0h

    +04h: 4 байта — ESP для CPL = 0

    -> D25A9FB8h

    +08h: 4 байта — SS для CPL = 0

    -> 30h

    +0Ch: 4 байта — ESP для CPL = 1

    -> 00h

    +10h: 4 байта — SS для CPL = 1

    -> 00h

    +14h: 4 байта — ESP для CPL = 2

    -> 00h

    +18h: 4 байта — SS для CPL = 2

    -> 00h

    +1Сh: 4 байта — CR3

    -> 00F0D000h

    +20h: 4 байта — EIP
    +24h: 4 байта — EFLAGS
    +28h: 4 байта — ЕАХ
    +2Ch: 4 байта — ЕСХ
    +30h: 4 байта — EDX
    +34h: 4 байта — ЕВХ
    +38h: 4 байта — ESP
    +3Ch: 4 байта — ЕВР
    +40h: 4 байта — ESI
    +44h: 4 байта — EDI
    +48h: 4 байта — ES
    +4Ch: 4 байта — CS
    +50h: 4 байта — SS
    +54h: 4 байта — DS
    +58Н: 4 байта — FS
    +5Ch: 4 байта — GS
    +60h: 4 байта — LDTR
    +64h: 2 байта — слово флагов задачи. Бит 0 — флаг Т: вызывает #DB при переключении на задачу остальные биты не определены и равны нулю

    -> Все нули (с 20h по 64h)

    +66h: 2 байта — адрес битовой карты ввода-вывода. Это 16-битное смещение от начала TSS, по которому начинается битовая карта разрешения ввода-вывода (см. главы 10.7.4 и 10.9.2) и заканчивается битовая карта перенаправления прерываний (см. главу 10.9.1) данной задачи.

    -> 0068h

    А вот сама I/O Permission Map:

    0068h:
    FF,FF,00,00 - 03,00,00,00 - 09,00,00,00 - 11,00,00,00
    8E,0E,00,00 - 03,00,00,00 - 55,55,55,55 - 00,00,00,00
    ...

    Отсюдова видно что разрешены, к примеру, порты 61h,63h, а порты 60h и 64h запрещены,

    или вот к примеру для диапазона 3C0h..3DFh все нули - видео разрешено.

    Эта хрень больше похожа на I/O permission map для app32 или V86.

    > Хм, а кто мешает тупо записать в дескриптор адрес своего
    > обработчика.

    Я видал одну (писал статейку) заshit'у, которая при запуске процедур из драйвера смотрела (правда не int 1 а int 14h/6h) код по вектору и проверяла его crc. Так что могут быть некоторые трудности.
     
  7. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    С этим тоже можно очень даже бороться. Во всяком случае когда речь идет об int1. Делаем свою IDT, размещаем ее таким образом, чтобы первые два дескриптора залезали на страничку, которая not present. Таким образом при генерации int 1 или попытке чтения/записи дескриптора int 1 получаем page fault, которое мы сами и обрабатываем. При попытке чтения подсовываем тот адрес обработчика, к-рый нужен защите :). Это вкратце. С подробностями все намного муторнее. Со SF этот трюк успешно прокатывал.
    Несколько лет назад :) Сейчас не знаю.
     
  8. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Medstrax

    В-принципе можно даже поменять EIP в GDT на "несуществующий" кусок. Кстати, в той заshit'е исключение 14h тоже было перехвачено :derisive:

    Если мне не изменяет память, кто-то все же сделал ее через GPF (видимо селектор менял а не EIP).
     
  9. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    ++

    Не, нифига я непонимаю нафига винде TSS... Вроде как нету у нее никаких задачек, к тому же если бы было хоть одно переключение, то поля регистрофф были бы заполнены. Тем не менее эта TSS32, sel 0x18 есть и ее селектор сидит в TaskRegister. Возможно, это вообще неиспользуецца, или используется "вручную"... хм, любопытна.
     
  10. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Chingachguk
    Я ж написал, для чего используется TSS. Если переключении на обработчик прерывания происходит смена уровней привилегий, то указатель стека будет взят из TSS. Поэтому указатели стеков в TSS заполнены, а все остальное -- нет.
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    не понимаю, почему только для этого
    неужели сохранение контекста "вручную" быстрее?
     
  12. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Не знаю точных цифр, но, вроде, быстрее. Тем более, что не обязательно сохранять все, что сохраняется в TSS -- селектор LDT, например, сохранять не обязательно -- в Win он LDT не используется. +по моим подозрениям (ничем не подтвержденным!) можно не сохранять сегментные регистры, если они не изменяются в обработчиках прерываний. Учитывая, что сегменты плоские, то обработчики прерываний запросто могу обращаться к сегментам с селекторами, доставшимися от менее привилегированного кода. Но это лишь мои догадки. +TSS штука нежная, шаг влево, шаг вправо и исключение. Но не думаю, что это остановило бы разработчиков от использования TSS. Так что скорее всего скорость...
     
  13. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Mika0x65
    хорошо, допустим при переключении сохраняются/восстанавливаются только EAX, EBX, ..., ESI, EDI, CR3, EFLAGS вот набросал примерный возможный алгоритм переключения
    Код (Text):
    1. switch_context:
    2. ; в EAX допустим указатель на хранилище регистров текущей задачи, в ECX - аналогично для задачи, на которую переключаемся
    3.     xchg eax, esp
    4.     add esp, 40
    5.     pusha ; сохраняем все регистры общего назначения
    6.     mov ebx, cr3
    7.     push ebx ; сохраняем CR3
    8.     pushfd ; сохраняем флаги
    9.     mov esp, ecx
    10.     popfd ; восстанавливаем флаги
    11.     pop ebx
    12.     mov cr3, ebx
    13.     popa ; восстанавливаем регистры общего назначения
    14.     xchg eax, esp
    15.     ret ; возврат уже по другому адресу, т. к ESP изменен посредством popa
    интересно, он быстрее апааратного или нет
     
  14. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Mika0x65,

    да я прочел что ты написал. Действительно, при возникновении прерывания от таймера (в 98 это вроде int 28h):

    int 28h: sel:ofs=28:C00047E0, DPL=3, Simulate_IO+03A0, IntG32

    Значение стека: SS:ESP=30:lol: 26E2F94h (а в TSS 18h SS0:ESP0=30:lol: 26E2FB8h).

    Но меня смущают (точнее я их не понимаю пока) две вещи:

    1. Каким образом TSS вступает в силу если механизм задач не работает (поле NT в EFLAGS равно нулю в ядре/app32/sys-драйверах а также если бы было хоть одно переключение, то поля регистров были бы ненулевые). Разве достаточно сделать ltr AX(<-18h) и для текущей (???) задачи (???) будет применена TSS??

    2. I/O Permission map. Явно непустая (есть еще несколько других TSS с нулевой I/O Permission Map) для TSS 18h, SoftIce кажет что кем перехвачено (и я ему охотно верю - проверил на нескольких характерных портах). Т.е. это явно сердечко управления доступа к портам в win. Но как она вступает в силу??? Я бы понял если бы винда создавала задачу (задачи) для каждого app32 и делала бы на нее переключение с этой TSS и этой Permission Map. Тогда бы "по теории" обращение из app32 вызывало бы исключение (а так и происходит!).

    :derisive:
     
  15. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Medstrax

    Если хук стоит по записи, то менять можно, а вот если и по записи и по чтению, то процессор зацикливается если пытаться что либо сделать. Собственно в SF скоро эта фишка будет (пока ее там нету, но SoftIce настолько некорректно работает с регистрами отладки, что запустить его под SF трудновато).
    Мои варианты:
    1) Меняем базу IDT, потом снимаем защиту DR регистров, потом восстанавливаем как было.
    2) Меняем временно физическую страницу в памяти (там гаде IDT) и т.д.
     
  16. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    rei3er
    Самое простое, я думаю, померять время сохранения с помощью 'rdtsc'.

    Chingachguk
    1. Почему не работает? Можно сказать, что работу свою TSS начинает выполнять как только загрузился регистр tr. А NT в EFLAGS не используется и не надо :). Просто смотря что считать работой.

    Что значит применена? После выполнения 'ltr' будет загружен регистр tr, и больше ничего. В этом случае TSS, если не вызвать явное переключение задач, будет использоваться только как место для хранения указателей стека и проверки прав при доступе к портам (если есть карта).

    2. В силу вступает сразу же, как только будет загружен регистр tr. Никто ведь не запрещает использовать один и тот же TSS для разных задач. Правда, карта доступа к портам для всех задач будет одинакова, но если это не противоречит условию, то ничего страшного в этом нет :).
     
  17. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Medstrax

    По крайней мере для борьбы с SF я так делал.

    Ну кажется много воды (в смысле со SF борются все, а готовых рабочих ехешек или исходников нет), да и отвлеклись от темы.
     
  18. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Mika0x65

    Очень интересно!

    Итак, получается вроде бы следующее:

    Если подготовить TSS и загрузить селектор TSS в TR, то:

    1. При прерывании стек инициализируется из TSS;
    2. При выполнении запрещенных in/out команд в Permission Map возникает исключение и управление передается в 0-е кольцо соответствующему обработчику.

    По поводу 2 есть вопрос: это касается всех задач из нижележащих колец или даже кода из 0-кольца? Вроде бы по моим опытам из нулевого кольца выполнение in/out команд не приводит к исключению - ?
     
  19. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Chingachguk

    Вообще TR инициализируется при переходе в защищенный режим однократно, а затем при переключении задач (кроме того есть еще флаг вложенной задачи) регистр TR автоматически загружается из GDT или IDT. В винде TSS заполнен неправильно (точнее несовсем правильно посмотри занчения ss: для др. колец защиты 1 или 2).
     
  20. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    зависит от маски разрешения ввода-вывода