Подскажите с SEH ?

Тема в разделе "WASM.WIN32", создана пользователем 7mm, 17 май 2010.

  1. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    gorodon
    в обычном exe всё то-же самое см. #12
     
  2. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Так, похоже вы правы. С LoadLibrary исключение обрабатывается и выполнение программы продолжается (слегка модифицировал обработчик). В чём может быть проблема, когда загрузка DLL осуществляется вручную? Память выделяется через VirtualAlloc с флагом PAGE_EXECUTE_READWRITE.
     
  3. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Вы были правы на счёт обработчика, он хитрее, чем я полагал:
    Код (Text):
    1. EXCEPTION_DISPOSITION __cdecl handler (
    2.     struct _EXCEPTION_RECORD *_ExceptionRecord,
    3.     void * _EstablisherFrame,
    4.     struct _CONTEXT *_ContextRecord,
    5.     void * _DispatcherContext
    6.     )
    7. {
    8.     lpData1 = (LPDWORD)&lpData1;
    9.  
    10.     _ContextRecord->Eip += 6;
    11.  
    12.     return ExceptionContinueExecution;
    13. }
     
  4. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Вот такой ещё интересный момент. Загрузка DLL происходит следующим образом: dll-loader.exe -> library1.dll -> library2.dll. В library1 присутствует код, который грузит как саму library1, так и library2. Так вот, после такой хитрой загрузки library1 работает в полном соответствии с SEH и т.д., а вот в library2 почему-то возникают описанные проблемы. То есть, при одном и том же коде -- разный результат... Странно всё. Тестирую, кстати, на W7.
     
  5. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    >VOID handler() { *lpData = (LPVOID)&lpData; }
    >LPDWORD lpData = NULL;

    Что в 'lpData' лежит? Нуль. Т.е. в хендлере ОП пишет по нулевому адресу и возникает ещё одно исключение. Что он хотел сделать:
    VOID handler() { lpData = (LPVOID)&lpData; }
    ...Ага, уже исправил.

    Y_Mur
    Не более обязательно, чем в других колбеках – если один не использует эти регистры, то и сохранять\восстанавливать их незачем. Более того, современные системы для обработки сех не полагаются на то, что пользовательский хендлер сохранит эти регистры (даже в сохранность esp не верят). Хотя да, полагаться на это мы бы не стали.

    7mm
    Если хочешь try\except без CRT, то можешь подключить только те кусочки, где определены нужные процедуры – и не нужны будут асм-вставки. Либо можешь свой _except_handler4\_except_handler3 написать, если MS не доверяешь. Опять-таки, выгода – достигается улучшенный контроль и не нужны асм-вставки. Можешь даже багу исправить.
     
  6. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    ohneуказал на IMAGE_DLLCHARACTERISTICS_NO_SEH.
    Это значение DllCharacteristics из _IMAGE_OPTIONAL_HEADER (заголовка pe-файла) - в msdn "The image does not use structured exception handling (SEH). No handlers can be called in this image."
    Значит нужна доп-я обработка при загрузке образа DLL-ки в память процесса, как это делает LoadLibrary...
    Может ohne подскажет как вручную "включить" SEH? :)
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    (хз чей топик, тоесть кто автор..)
    В самом верху этого раздела прикреплён мой топик. Почитать вам его не нужно, тогда попросите когонибудь почитать его за вас. Конкретно по вопросу: RtlDispatchException -> RtlIsValidHandler -> RtlLookupFunctionTable -> RtlCaptureImageExceptionValues проверяет в заголовке модуля флажёк IMAGE_DLLCHARACTERISTICS_NO_SEH, если взведён выполняется возврат с ошибкой, что значит хэндлер инвалидный и не может быть вызван.
    Он скажет сбросить этот флажёк, либо сбросить его в проекции модуля.
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Добился чтобы MSVC и масм генерировали практически одинаковый тестовый код.

    При этом masm вариант работает на ура - Оля отлично отлавливает бряк (по F2) в SEH обработчике и обработчик корректно исправляет адрес записи.

    А в MSVC варианте вместо перехода на бряк в SEH обработчике Оля пишет "отлаживаемая прога не способна обработать исключение"...
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Clerk
    В том топике по ключевому слову "NO_SEH" ничего не нашлось.
    Для exe тот-же флажок, или другой?
    Странно зачем MSVC вообще SEH блокирует.
     
  10. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Код (Text):
    1. Structure for Optional Header
    2. (+0x46) DllCharacteristics:          0x0000
    Как видно, флаг, запрещающий SEH, не установлен.
     
  11. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Только что проверил такую штуку: в Windows XP SP3 всё работает как по маслу. Проблемы возникают в W7. Вот здесь похожая проблема (http://wasm.ru/forum/viewtopic.php?id=33418) - там вроде бы дело в DEP.
     
  12. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    1. Если дело в этом
    т.е. в DEP, то ваша dll-ка вообще бы не работала. В любом случае, проверьте установку атрибутов на страницы памяти, где располагается сегмент кода - PAGE_EXECUTE_READWRITE

    2. Clerk говорит о том, что "...RtlCaptureImageExceptionValues проверяет в заголовке модуля флажёк IMAGE_DLLCHARACTERISTICS_NO_SEH...". Но у вас "модуля" нет - вы загружали dll-ку вручную, может поэтому так и происходит...
     
  13. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Да, флаг стоит. В коде стоит и в Olly RWX отображается.

    Да, модуль загружается вручную. Не регистрируется... Может быть дело в этом. Однако, в посте #24 я описал принцип загрузки DLL. Получается, что всё-таки одна из двух загружаемых (идентично?) DLL работает, включая SEH.
     
  14. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Смотри там же(http://wasm.ru/forum/viewtopic.php?id=33418) #10:
    "
    чего не было сказано: если хендлер находится в памяти, выделенной VirtualAlloc, то, кроме всего прочего, проверяются флажки процесса Pcb.Flags (_KEXECUTE_OPTIONS): ExecuteDispatchEnable и ImageDispatchEnable. если они оба сброшены, то RtlIsValidHandler вернёт false.
    "
    -вот это надо-бы проверить
     
  15. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    У меня GetProcessDEPPolicy возвращает: dwFlags = 0, bPermanent = TRUE.
     
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Так а это, твоя длл добавляется в список загруженных модулей (их, кстати, очень много)?
    SEH обработан не будет, если адрес хендлера указывает вне зарегистрированных модулей. Это часть защиты от атак переполнения буффера - чтобы нельзя было перетереть адрес обработчика на стеке.
     
  17. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Ну похоже на то... Отключил DEP, дело в нём -- ничего не изменилось. Получается, что в W7 можно забыть про 'хитрую' загрузку DLL с возможностью использования SEH без MSVCRT?
     
  18. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Да ёлки, я разве про DEP писал? То, что я описал - встроенная фича обработки SEH. Не отключается afaik
     
  20. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Да это я просто до вашего комментария пробовал. Кстати, если за обработку исключений отвечает KiUserExceptionDispatcher, то можно наверняка его подкрутить, чтобы поменять логику обработки SEH для незарегистрированных модулей?