Fault при перезагрузке GDT в защищенном режиме

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

  1. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Medstrax
    слушай, почитай внимательно псевдокод
    там четко написано, когда может генерироваться #GP по селектору
    по поводу места, где описаны исключения
    как ты мог заметить, RETF инструкция не описана отдельно
    RET и RETF объеденены в одну инструкцию RET и описанные исключения - это все исключения, которые могут генерироваться при выполнении этой обобщенной инструкции RET, т. е исключения при выполнении RETF и RET
    а уже конкретные действия для RET и RETF описываются псевдокодом для каждой инструкции в отдельности
    и в псевдокоде для RET четко можно заметить, что #GP по селектору не генерируется
    это раз
    во-вторых, даже логически понятно, что в этом случае не может быть никакого #GP по селектору хотя бы потому, что SS никто не трогал
    все условия (в том числе ссответствие селектора лимиту GDT (или LDT)) проверяются только при его загрузке и если он загружен успешно, то нет смысла опять проверять все условия при работе со стеком, если SS не затрагивается
     
  2. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Разговор ни о чем. Надо просто вставить перед ret - mov ax,8 mov ss,ax
    Если прав я - тогда прога свалится где то после ret'а
    Одно фигово, проверить на чем валится - нереально, при такой gdt, в к-рой даже сегмент кода неопределен, мы даже исключение поймать не сможем. А в том, что bochs
    (или любой другой эмулятор) правильно сэмулирует данную ситуацию я сомневаюсь.
    Особо тонкие моменты они не эмулируют, сталкивался неоднократно ;)
    З.Ы. А твои рассуждения насчет логики работы ret - это только твои рассуждения,
    просто в мане этот момент можно трактовать неоднозначно.
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    да все там однозначно
    протри глаза
    споришь ни о чем ты
     
  4. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Беру свои слова обратно
    Сейчас проверил на реальной машине. В GDTR можно грузить что угодно, хоть нули, хоть
    FFFFh и FFFFFFFFh. До тех пор пока сегментные регистры не меняются или не требуется их повторная загрузка - процу фиолетово, все работает как часы.
    Так что проблема не в этом :)
    rei3er, сори ;) только грубить то зачем?
     
  5. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    извини, не сдержался
    но и ты пойми, это же все-таки не первый мой пост был
     
  6. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Гм, я тоже не первый год курю, 15 лет асмом занимаюсь. Однако ж вот, приплыл :))).
    Бывает, блин. Тем не менее проблема так и не решена - почему система валится после lgdt?
    Естесно, что при такой gdt она свалится рано или поздно в любом случае, после первого же исключения или межсегментной передачи управления. Непонятно - почему сразу?
     
  7. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    с точки зрения человека - сразу
    а вот с точки зрения CPU - где-то после
    Код (Text):
    1. in al, 70h
    2.         and al, 7Fh
    3.         out 70h, al ; вот этой инструкции
    4.         sti
    5.         ret
    вроде KonstantinBart про "сразу" написал в контексте того, что если, закомментировать lgdt, то все работает
     
  8. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Гы, увидел - он это дело в сайсе отлаживал, теперь понятно почему после lgdt все падает :)))
     
  9. KonstantinBart

    KonstantinBart New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    20
    Я в софт айсе отлаживал только чтобы показать значения всех нужных регистров и дампов памяти перед выполнение lgdt.....а само собой что сайс не позволит мне выполнить эту команду, так как я и его как бы грохаю!
    Я еще тестировал на чистой WinXP.....и там просто комп перегружался......
    А на виртуальной машине - вываливался Fault и перезагрузка или выключение ВМ.
     
  10. KonstantinBart

    KonstantinBart New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    20
    Ну я как понял надо настроить сегмент кода, данных и стека, причем:
    Селектор, загруженный в SS, должен быть селектором сегмента данных, доступного для чтения/записи.
    Селектор, загруженный в CS, должен быть селектором сегмента кода.
    Селектор, загруженный в регистры DS, ES, FS, GS, должен быть либо селектором сегмента данных, либо селектором сегмента кода, доступного для чтения, либо нулевым селектором.

    Я вот добавил в свой код еще и дескрипторы стека и кода...
    Теперь прога валится на "mov ss, ax"...

    Код (Text):
    1. .386p
    2. .model flat
    3. public _GetCr0@0
    4.  
    5. .stack 100h
    6. .data
    7.  
    8. GDT     db 0            ;0 descr
    9.         db 0
    10.         db 0
    11.         db 0
    12.         db 0
    13.         db 0
    14.         db 0
    15.         db 0
    16.  
    17.         db 0FFh        ;data descr
    18.         db 0FFh
    19.         db 0
    20.         db 0
    21.         db 0
    22.         db 10010010b   ;92h
    23.         db 10001111b   ;8Fh
    24.         db 0
    25.  
    26.         db 0FFh        ;stack descr
    27.         db 0FFh
    28.         db 0
    29.         db 0
    30.         db 0
    31.         db 10010110b   ;96h
    32.         db 10001111b   ;8Fh
    33.         db 0
    34.  
    35.         db 0FFh        ;code descr
    36.         db 0FFh
    37.         db 0
    38.         db 0
    39.         db 0
    40.         db 10011010b    ;9Ah
    41.         db 0
    42.         db 0
    43.  
    44. gdtr    dw $ - GDT - 1
    45.         dd ?
    46.  
    47. .code
    48.  
    49. _GetCr0@0:
    50.     jmp short _main
    51.  
    52. _main:
    53.         call disable_interrupts
    54.         call initialize_gdt
    55.         call enable_interrupts
    56.         ret
    57.  
    58. disable_interrupts:
    59.         cli
    60.         in al, 70h
    61.         or al, 80h
    62.         out 70h, al
    63.         ret
    64.  
    65. initialize_gdt:
    66.         mov  eax, 0
    67.         add eax, offset GDT
    68.         mov dword ptr gdtr + 2, eax
    69.         ;lgdt fword ptr gdtr
    70.  
    71.         mov ax, 16    ;for stack
    72.         mov ss, ax
    73.  
    74.         mov ax, 24    ;for code
    75.         mov cs, ax
    76.  
    77.         mov ax, 8    ;for data
    78.         mov ds, ax
    79.  
    80.         ret
    81.  
    82. enable_interrupts:
    83.         in al, 70h
    84.         and al, 7Fh
    85.         out 70h, al
    86.         sti
    87.         ret
    88.  
    89. end _GetCr0@0
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    ты же lgdt не выполнил
    поэтому gdtr содержит адрес GDT Windows, а так как по селектору 16 не обязательно будет находится валидный дескриптор сегмента данных, доступный на чтение, от этого и вылет
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    rei3er
    дык валится то на "mov ss, ax". или ты учитывая предыдущие посты автора предполагаешь что метод обнаружения ошибки - это комментирование кода до тех пор пока не заработает?
     
  13. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    n0name
    я на код смотрю
    зачем гадать?
    KonstantinBart
    я только сейчас заметил, что
    у тебя все дескрипторы 16-ти разрядные, так нужно?
    и кроме того
    инструкции
    Код (Text):
    1. mov cs, ax
    нет
     
  14. Sedov

    Sedov New Member

    Публикаций:
    0
    Регистрация:
    6 дек 2007
    Сообщения:
    8
    KonstantinBart, Юрьев "Assembler" там все оччень подробно расписано. И потренируся хотя бы на виртуальной машине попрыгать из реала в защищеный и обратно.
     
  15. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    В рез-те обсуждения темы появилась интересная мысля. Тот факт, что в GDTR можно загружать что угодно и нормально при этом работать (естесно если при этом не будут возникать исключения и загрузка новых селекторов) - можно использовать для антиотладки.
    Любые трапы - на I/O, на данные или код - будут рушить систему, если, к примеру, забить в GDTR нули. Естесно, что речь идет о ринг0 и, естесно, наш код должен выполняться при закрытых прерываниях. Может, конечно, изобрел велосипед, но лично я с таким приемом не сталкивался. Еще нужно проверить, можно ли воспользоваться этой фишкой, чтобы обломать
    трапы на I/O с помощью SMI# Не факт, что при выходе из SMM проц не упадет, если GDTR
    будет кривым
     
  16. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    а если дескрипторы шлюзов IDT будут содержать селектор в LDT а не в GDT?
    тут надо будет повозиться
     
  17. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Но это чревато, так как обработчик тоже должен загрузить селекторы. В итоге получаем triple fault.
     
  18. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Ну дык о чем и речь. Если наш код выполняется в обычном режиме, не возникает никаких исключений. Если мы пытаемся его дебажить - система рухнет.
     
  19. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    При загрузке селектора из LDT все равно идет косвенное обращение к GDT. По идее тоже должно все падать.
     
  20. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    в LDTR кэшируется дескриптор LDT из GDT
    обращения к GDT в случае использования селектора LDT нет