Изучаю тут SEH спокойно =/ по Питреку. Написал небольшую демопрогу (см. ниже). Так вот без отладчика всё окей, и в отладчике всё окей если просто по F9 запустить. Но если поставить бряк на месте где происходит исключение, и после остановки трассировать вручную, то в первый раз всё нормально - ACCESS_VIOLATION и падаем в обработчик. После возвращений из обработчика eax содержит нормальное значение ктр установили в обработчике. При попытке выполнить инструкцию вылетает снова исключение SINGLE_STEP_EVENT и опять падаем в обработчик??? после повторного возвращение всё нормально. Как я понял из гугла SINGLE_STEP_EVENT - исключение возникающие при выполнении очередной команды когда установлен флаг трассировки. WTF?! с какого перепугу он установлен стал и почему просто при запуске всё нормально?? Код (Text): main: ;Устанавливаем наш обработчик прерываний assume fs:nothing lea eax, handler ;Помещаем указатель на обработчик прерывания в стек - EXCEPTION_REGISTRATION.handler push eax push fs:[0] ;Помещаем указатель на предыдущий обработчик в стек - EXCEPTION_REGISTRATION.prev mov fs:[0], esp ;Сохраняем в TIB указатель на нашу структуру EXCEPTION_REGISTRATION xor eax, eax ;Вызываем исключение ACCESS_VIOLATION mov dword ptr [eax], 01h invoke MessageBox, NULL, addr pTextAfter, addr pTitleAfter, MB_OK ;Убираем наш обработчик pop eax ;Достаём из стека указатель на предыдущую ;структуру EXCEPTION_REGISTRATION mov fs:[0], eax ;Устанавливаем его в TIB add esp, 8 ;Очищаем стек от гавна ^_____^ ;(в смысле выравниваем ~_~;) invoke ExitProcess, 0 ;======================================================================================================================== ;Наш обработчик исключений, нужно ли восстанавливать в нём регистры, ктр спользовали? ;"C" - тк у Питрека функция описана как _cdecl handler proc C ExceptionRecord:DWORD, EstablisherFrame:DWORD, ContextRecord:DWORD, DispatcherContext:DWORD invoke MessageBox, NULL, addr pText, addr pTitle, MB_OK mov eax, ContextRecord assume eax: ptr CONTEXT lea ebx, scratch mov [eax].regEax, ebx mov eax, ExceptionContinueExecution ret handler endp end main
Если происходит исключение отличное с взведённым TF, то можно считать аномалией - этот флажёк передаётся в диспетчер исключений, после исполнения первой инструкции которого генерируется трассировочное исключение и TF сбрасывается. В стеке получаются два фрейма, один из которых лишний(при трассировке TF взводится):
Clerk Здесь не тот случай. Описанное поведение имеет мало отношения к ОП-посту, на самом деле. h3rmit Olly выставляет TF при выполнении трассировки. Т.е. после выполнения каждой инструкции возникает исключение, которое Olly ловит. Т.е. перед исполнением mov [0], eax выставляется флаг трассировки, запускается выполнение... И возникает исключение ACCESS_VIOLATION. Trace Flag при выполнении инструкции не был сброшен – инструкция по сути так и не исполнена же (в хендлере можешь посмотреть на EFlags в контексте – там взведён бит 8, TF). Так вот, корень всего зла в том, что после выхода из хендлера и восстановления контекста (в том числе EFlags с установленным TF) Olly "забывает", что это она установила TF. И показывает пользователю возникающее после выполнения инструкции трассировочное исключение, а при бездействии передаёт исключение программе.
Sol_Ksacap Это внутренние баги в приложении(в данном случае оля), их много и если они мешают отладке следует какимто образом обходить их или взять другой дебуггер, я описал системны баг, так вопрос понял.