SEH

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

SEH

Сообщение Twister » 15.05.2006 (Пн) 7:45

Всем доброго времени суток.

Просто стало интересно. У каждого потока в системе есть свой дефолтный обработчик исключений (если, конечно, мы не сменили его на свой), который находится в конце списка EXCEPTION_REGISTRATION. Дефолтный обработчик, в отличии от наших, всегда обрабатывает исключения. Поэтому самое страшное, что мы можем узреть на мониторе - это БСОД :) . Теперь вопрос - а что произойдет, если система не найдет в списке EXCEPTION_REGISTRATION обработчик, который обработает исключение?..
А я все практикую лечение травами...

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 15.05.2006 (Пн) 8:04

Самое страшное, что мы можем увидеть в юзермоде (когда вывалилось обычное приложение) - это окошко UAE (Unrecoverable Application Error) с предложением отправить отчет к чертовой матери.

Обработчик, выдающий "синий экран", работает в режиме ядра и включается при обнаружении фатальных ошибок в драйверах и системных приложениях из ring 0. И, по идее, он должен работать всегда. (Mark Russinovich "Inside the Blue Screen")
Моду создают модоки, а распространяют модозвоны.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 8:09

Про ring 3 ни кто и не говорил... :wink:

Mark Russinovich писал(а):И, по идее, он должен работать всегда.
По идее конечно, но теоритически все таки возможно его убрать (точнее не саму процедуру обработчика, а элемент в списке, который кажет на процедуру).
А я все практикую лечение травами...

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 15.05.2006 (Пн) 9:12

Если все спроектировано грамотно, то даже из драйвера ты не уберешь этот обработчик. Он же и сработает при первой попытке сделать "ню-ню" - IRQL_NOT_LESS_OR_EQUAL. Другое дело, намеренно допустить ошибку в ntoskrnl - затирать адрес нужной процедуры. Но для этого нужно: иметь код ntoskrnl, SDK, компилятор, умение и желание этим всем заниматься.

А если спроектировано неграмотно, тогда сам знаешь что будет. Система просто тихо сдохнет :)
Моду создают модоки, а распространяют модозвоны.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 10:32

Ты прав - чтоб с уверенностью сказать что же произойдет, нужно основательно засесть за дизасм и ковырять ядро. А так и преждевременный геморой заработать недолго :lol: . Вообще, напрашиваются два варианта ответа - либо моментальная перезагрузка системы, либо ее смерть (подвисон). Просто я задал этот вопрос в надежде, что кто-то уже знает ответ. А мучать ядро попусту у меня (да и наверное ни у кого) желания нет...
А я все практикую лечение травами...

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 15.05.2006 (Пн) 11:03

Скорее зависнет. Мгновенная перезагрузка бывает когда плохой контакт модуля памяти или какая-то важная железка подыхает (типа USB-порта). Подождем авторитетного совета Темыча (ему не лениво зарабатывать преждевременный гемморой)
Моду создают модоки, а распространяют модозвоны.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 11:48

1. Чтобы с уверенностью сказать, что произойдёт, достаточно взять и попробовать ;-)
2. Ладно, как раз прямо сейчас ковыряюсь с SEH -- посмотрю заодно и на этот счёт...


Но уточню вопрос. Вы всё ещё про юзермод? тогда при чём здесь ядро?
Дефолтный обработчик лежит в kernel32, бегалка по списку обработчиков лежит в ntdll. Ничего относящегося к SEH в ядре вроде как и нет :roll:
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 12:06

Ничего относящегося к SEH в ядре вроде как и нет

А БСОД? Откуда тогда он берется в ring 0 ? Кто-то же его вызывает... :wink:
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 12:14

Кстати, основываясь на статье Мэта Питрека и на коментариях к ней, я делаю вывод, что код, который управляет SEH лежит именно в ядре... Да и чисто по логике вещей он там и должен находиться...
бегалка по списку обработчиков лежит в ntdll
Сто процентов даю, что эта самая бегалка (RtlUnwind) проходит через шлюз int 2E прямо в ядро...
Последний раз редактировалось Twister 15.05.2006 (Пн) 12:24, всего редактировалось 2 раз(а).
А я все практикую лечение травами...

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 15.05.2006 (Пн) 12:18

Я не про юзермод, а насчет Твистера не уверен :)
Моду создают модоки, а распространяют модозвоны.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 12:23

hCORe писал(а):Я не про юзермод, а насчет Твистера не уверен

Twister писал(а):Про ring 3 ни кто и не говорил...
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 12:29

Во, Темыч, нашел я то что надо:
Matt Pietrek писал(а):в Intel-архитектуре возникновение исключения вызывает передачу управления по вектору в обработчик находящийся в нулевом кольце защиты, т.е. в обработчик режима ядра (kernel mode). Обработчик определен соответствующим исключению элементом таблицы дескрипторов прерываний (она же - Interrupt Descriptor Table, или просто - IDT).
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 12:35

Twister писал(а):
hCORe писал(а):Я не про юзермод, а насчет Твистера не уверен

Twister писал(а):Про ring 3 ни кто и не говорил...

Тогда почему всё это в форуме про VB?


В ядро не полезу, мне и в юзермоде есть в чём поковыряться...
Последняя находка: если ненароком убить кадр SEH, то рантайм VB перестаёт мочь работать с файлами. Оказывается, указатель на таблицу открытых файлов рантаймом хранится в кадре SEH :roll:
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 12:38

Тогда почему всё это в форуме про VB?

Потому что это мой любимый форум, хотя на WASMе я уже задал этот вопрос.
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 12:41

Оказывается, указатель на таблицу открытых файлов рантаймом хранится в кадре SEH
Это если файл открыть через обычный Open? А если через АПИ?
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 13:31

Twister писал(а):
Тогда почему всё это в форуме про VB?

Потому что это мой любимый форум, хотя на WASMе я уже задал этот вопрос.

:-?
Специально для таких случаев предусмотрен Трёп.
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 13:40

Специально для таких случаев предусмотрен Трёп
В принципе да, согласен...
Кстати, по теме: на WASMе высказали мнение, что ни чего страшного не произойдет, система лишь прибьет процесс.
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 14:42

Twister писал(а):Кстати, основываясь на статье Мэта Питрека и на коментариях к ней, я делаю вывод, что код, который управляет SEH лежит именно в ядре... Да и чисто по логике вещей он там и должен находиться...
бегалка по списку обработчиков лежит в ntdll
Сто процентов даю, что эта самая бегалка (RtlUnwind) проходит через шлюз int 2E прямо в ядро...

Во даёшь -- статью Пиетрека прочитал, а примеры кода к ней -- нет :lol:

Figure 12: RtlUnwind Pseudocode
Код: Выделить всё

void _RtlUnwind( PEXCEPTION_REGISTRATION pRegistrationFrame,
                  PVOID returnAddr,  // Not used! (At least on i386)
                  PEXCEPTION_RECORD pExcptRec,
                  DWORD _eax_value )
{
     DWORD   stackUserBase;
     DWORD   stackUserTop;
     PEXCEPTION_RECORD pExcptRec;
     EXCEPTION_RECORD  exceptRec;   
     CONTEXT context;

     // Get stack boundaries from FS:[4] and FS:[8]
     RtlpGetStackLimits( &stackUserBase, &stackUserTop );

     if ( 0 == pExcptRec )   // The normal case
     {
         pExcptRec = &excptRec;

         pExcptRec->ExceptionFlags = 0;
         pExcptRec->ExceptionCode = STATUS_UNWIND;
         pExcptRec->ExceptionRecord = 0;
         // Get return address off the stack
         pExcptRec->ExceptionAddress = RtlpGetReturnAddress();
         pExcptRec->ExceptionInformation[0] = 0;
     }

     if ( pRegistrationFrame )
         pExcptRec->ExceptionFlags |= EXCEPTION_UNWINDING;
     else
         pExcptRec->ExceptionFlags|=(EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND);

     context.ContextFlags =
         (CONTEXT_i486 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);

     RtlpCaptureContext( &context );

     context.Esp += 0x10;
     context.Eax = _eax_value;

     PEXCEPTION_REGISTRATION pExcptRegHead;

     pExcptRegHead = RtlpGetRegistrationHead();  // Retrieve FS:[0]

     // Begin traversing the list of EXCEPTION_REGISTRATION
     while ( -1 != pExcptRegHead )
     {
         EXCEPTION_RECORD excptRec2;

         if ( pExcptRegHead == pRegistrationFrame )
         {
             _NtContinue( &context, 0 );
         }
         else
         {
             // If there's an exception frame, but it's lower on the stack
             // then the head of the exception list, something's wrong!
             if ( pRegistrationFrame && (pRegistrationFrame <= pExcptRegHead) )
             {
                 // Generate an exception to bail out
                 excptRec2.ExceptionRecord = pExcptRec;
                 excptRec2.NumberParameters = 0;
                 excptRec2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
                 excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;   

                 _RtlRaiseException( &exceptRec2 );
             }
         }

         PVOID pStack = pExcptRegHead + 8; // 8==sizeof(EXCEPTION_REGISTRATION)

         if (    (stackUserBase <= pExcptRegHead )   // Make sure that
             &&  (stackUserTop >= pStack )           // pExcptRegHead is in
             &&  (0 == (pExcptRegHead & 3)) )        // range, and a multiple
         {                                           // of 4 (i.e., sane)
             DWORD pNewRegistHead;
             DWORD retValue;

             retValue = RtlpExecutehandlerForUnwind(
                             pExcptRec, pExcptRegHead, &context,
                             &pNewRegistHead, pExceptRegHead->handler );

             if ( retValue != DISPOSITION_CONTINUE_SEARCH )
             {
                 if ( retValue != DISPOSITION_COLLIDED_UNWIND )
                 {
                     excptRec2.ExceptionRecord = pExcptRec;
              excptRec2.NumberParameters = 0;
                     excptRec2.ExceptionCode = STATUS_INVALID_DISPOSITION;
                     excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;   

                     RtlRaiseException( &excptRec2 );
                 }
                 else
                     pExcptRegHead = pNewRegistHead;
             }

             PEXCEPTION_REGISTRATION pCurrExcptReg = pExcptRegHead;
             pExcptRegHead = pExcptRegHead->prev;

             RtlpUnlinkHandler( pCurrExcptReg );
         }
         else    // The stack looks goofy!  Raise an exception to bail out
         {
             excptRec2.ExceptionRecord = pExcptRec;
             excptRec2.NumberParameters = 0;
             excptRec2.ExceptionCode = STATUS_BAD_STACK;
             excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;   

             RtlRaiseException( &excptRec2 );
         }
     }

     // If we get here, we reached the end of the EXCEPTION_REGISTRATION list.
     // This shouldn't happen normally.

     if ( -1 == pRegistrationFrame )
         NtContinue( &context, 0 );
     else
         NtRaiseException( pExcptRec, &context, 0 );

}


100% чистый юзермод.
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 14:57

Темыч, ты чего? Это же псевдокод...
Еще раз напишу:
Matt Pietrek писал(а):в Intel-архитектуре возникновение исключения вызывает передачу управления по вектору в обработчик находящийся в нулевом кольце защиты, т.е. в обработчик режима ядра (kernel mode). Обработчик определен соответствующим исключению элементом таблицы дескрипторов прерываний (она же - Interrupt Descriptor Table, или просто - IDT).
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 15:00

И где ты в этом псевдокоде видишь переход в ядро?
Или хоть одну инструкцию, которая бы его требовала?
Наконец: заглянуть в ntdll самому, и удостовериться -- религия не позволяет?
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 15:06

Конечно нигде. Это же псевдокод. Зато вижу еще кучу АПИ, псевдокод которых не приводиться.
Если Питрек пишет, что в Intel-архитектуре возникновение исключения вызывает передачу управления по вектору в обработчик находящийся в нулевом кольце защиты, то переход должен быть...
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 15:28

Ещё раз поясню: обработкой SEH в юзермоде занимается ntdll. Она устанавливает нижний обработчик, который выводит окошко "программа выполнила недопустимую операцию". Если его удалить -- просто завершится процесс.

Именно про SEH в юзермоде написана статья Пиетрека.

В ядре SEH свой. Я не знаю в подробностях, как он там реализован, но с юзермодным SEH он не пересекается.

Обработчик исключений в ядре (функция KiDispatchException) примерно такой:
Код: Выделить всё
Если исключение произошло в пользовательском режиме
    Вызвать KeUserExceptionDispatcher
    ' Происходит переход в юзермод, и выполняется ntdll!KiUserExceptionDispatcher.
    ' Он сам пройдётся по обработчикам и сделает, что ему надо.
Иначе
    Вызвать RtlDispatchException
    ' Он сам пройдётся по обработчикам и сделает, что ему надо.
    ' Если никто не согласится обработать исключение, управление вернётся сюда
    KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED)


Т.е. убить тот кадр SEH, который вызывает KMODE_EXCEPTION_NOT_HANDLED, ты не можешь -- потому что такого кадра нет.
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 15:39

Ну вот теперь я понял что ты имел ввиду. Гуд.
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 21:12

А вот и правильный ответ (надеюсь).
ms-rem писал(а):Последний из обработчиков (который ставит система) прибивает процесс. Если не один обработчик вобще не будет найден, то снова возникнет исключениие, и опять будет поиск обработчика... Процесс войдет в бесконечный цикл и будет 100% грузить процессор.
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 21:43

Twister писал(а):А вот и правильный ответ (надеюсь).
ms-rem писал(а):Последний из обработчиков (который ставит система) прибивает процесс. Если не один обработчик вобще не будет найден, то снова возникнет исключениие, и опять будет поиск обработчика... Процесс войдет в бесконечный цикл и будет 100% грузить процессор.

Применительно к режиму ядра -- полный бред. Ядреный код не выполняется в контексте какого-то процесса (вернее, выполняется в контексте случайного процесса).

Ну, положим, мы убили какой-то случайный процесс, который попал под горячую руку -- а управление куда возвращать? Если исключение возникло при каком-нибудь высоком IRQL, то кто нам понизит IRQL обратно -- ведь обработчика мы убили?

Всё равно у системы не будет другого выхода, кроме синего экрана.


Ну хорошо, а ms-rem чем-то обосновывает свой ответ? Или это непогрешимый и непререкаемый авторитет?
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 21:49

Нет, не такой уж авторитет, но человек, к которому лично я прислушиваюсь (так же как к GSerg-у или к тебе). Насколько я понял - он имел ввиду юзермод.
А я все практикую лечение травами...

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 21:54

Ядреный код
Это как? :lol:
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 22:08

Twister писал(а):Нет, не такой уж авторитет, но человек, к которому лично я прислушиваюсь (так же как к GSerg-у или к тебе). Насколько я понял - он имел ввиду юзермод.

Ну, в юзермоде в такое можно поверить. А можно и не поверить...
Чесслово, надо бы проверить.
Изображение

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 15.05.2006 (Пн) 22:15

Гм... я сейчас работаю над проблемой с хэндлами. Хочу статейку написать. Потом может сяду за SEH.
А я все практикую лечение травами...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 15.05.2006 (Пн) 22:29

Ну хорошо, вот тебе иллюстрация из трёх строчек:
Код: Выделить всё
   xor eax,eax
   mov dword ptr fs:[eax], -1
   mov byte ptr [eax], 0


Помирает тихо и беззвучно. Никакой 100% загрузки нет.
Изображение

След.

Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 131

    TopList  
cron