Olly+SEH: Странное поведение.

Тема в разделе "WASM.BEGINNERS", создана пользователем h3rmit, 12 июл 2009.

  1. h3rmit

    h3rmit New Member

    Публикаций:
    0
    Регистрация:
    9 июн 2009
    Сообщения:
    28
    Изучаю тут SEH спокойно =/ по Питреку. Написал небольшую демопрогу (см. ниже).
    Так вот без отладчика всё окей, и в отладчике всё окей если просто по F9 запустить.
    Но если поставить бряк на месте где происходит исключение, и после остановки трассировать вручную, то в первый раз всё нормально - ACCESS_VIOLATION и падаем в обработчик. После возвращений из обработчика eax содержит нормальное значение ктр установили в обработчике. При попытке выполнить инструкцию вылетает снова исключение SINGLE_STEP_EVENT и опять падаем в обработчик??? после повторного возвращение всё нормально. Как я понял из гугла SINGLE_STEP_EVENT - исключение возникающие при выполнении очередной команды когда установлен флаг трассировки. WTF?! с какого перепугу он установлен стал и почему просто при запуске всё нормально??

    Код (Text):
    1. main:
    2.     ;Устанавливаем наш обработчик прерываний
    3.    
    4.     assume  fs:nothing
    5.  
    6.     lea eax, handler        ;Помещаем указатель на обработчик прерывания в стек - EXCEPTION_REGISTRATION.handler
    7.     push    eax
    8.     push    fs:[0]              ;Помещаем указатель на предыдущий обработчик в стек - EXCEPTION_REGISTRATION.prev      
    9.                          
    10.     mov fs:[0], esp     ;Сохраняем в TIB указатель на нашу структуру EXCEPTION_REGISTRATION
    11.  
    12.     xor eax, eax                ;Вызываем исключение ACCESS_VIOLATION
    13.     mov dword ptr [eax], 01h
    14.    
    15.     invoke  MessageBox, NULL, addr pTextAfter, addr pTitleAfter, MB_OK
    16.  
    17.     ;Убираем наш обработчик
    18.  
    19.     pop eax             ;Достаём из стека указатель на предыдущую
    20.                                                  ;структуру EXCEPTION_REGISTRATION
    21.     mov fs:[0], eax            ;Устанавливаем его в TIB
    22.     add esp, 8                  ;Очищаем стек от гавна ^_____^
    23.                                                  ;(в смысле выравниваем ~_~;)
    24.  
    25.     invoke  ExitProcess, 0
    26.  
    27. ;========================================================================================================================
    28.  
    29. ;Наш обработчик исключений, нужно ли восстанавливать в нём регистры, ктр спользовали?
    30. ;"C" - тк у Питрека функция описана как _cdecl
    31. handler proc    C   ExceptionRecord:DWORD, EstablisherFrame:DWORD, ContextRecord:DWORD, DispatcherContext:DWORD
    32.  
    33.     invoke  MessageBox, NULL, addr pText, addr pTitle, MB_OK
    34.    
    35.     mov eax, ContextRecord
    36.     assume  eax: ptr CONTEXT
    37.  
    38.     lea ebx, scratch
    39.     mov [eax].regEax, ebx
    40.  
    41.     mov eax, ExceptionContinueExecution
    42.    
    43.     ret
    44.  
    45. handler endp
    46.  
    47. end main
     
  2. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    F7-F8 (я так полагаю речь о олли дебаг была) = SINGLE_STEP_EVENT
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Если происходит исключение отличное с взведённым TF, то можно считать аномалией - этот флажёк передаётся в диспетчер исключений, после исполнения первой инструкции которого генерируется трассировочное исключение и TF сбрасывается. В стеке получаются два фрейма, один из которых лишний(при трассировке TF взводится):
    [​IMG]
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    *отличное от STATUS_SINGLE_STEP(#DB).
     
  5. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Clerk
    Здесь не тот случай. Описанное поведение имеет мало отношения к ОП-посту, на самом деле.

    h3rmit
    Olly выставляет TF при выполнении трассировки. Т.е. после выполнения каждой инструкции возникает исключение, которое Olly ловит. Т.е. перед исполнением mov [0], eax выставляется флаг трассировки, запускается выполнение... И возникает исключение ACCESS_VIOLATION. Trace Flag при выполнении инструкции не был сброшен – инструкция по сути так и не исполнена же (в хендлере можешь посмотреть на EFlags в контексте – там взведён бит 8, TF). Так вот, корень всего зла в том, что после выхода из хендлера и восстановления контекста (в том числе EFlags с установленным TF) Olly "забывает", что это она установила TF. И показывает пользователю возникающее после выполнения инструкции трассировочное исключение, а при бездействии передаёт исключение программе.
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Sol_Ksacap
    Это внутренние баги в приложении(в данном случае оля), их много и если они мешают отладке следует какимто образом обходить их или взять другой дебуггер, я описал системны баг, так вопрос понял.