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

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

  1. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Вот такая ситуация. Собираю DLL без использования MSVCRT. При сборке стоит флаг /SAFESEH:NO. В коде устанавливаю SEH стандартным образом:
    Код (Text):
    1. LPDWORD lpData = NULL;
    2. VOID handler() { *lpData = (LPVOID)&lpData; }
    3. ...
    4.     __asm { int 3 }
    5.     __asm {
    6.         push offset handler
    7.         push fs:[0]
    8.         mov fs:[0], esp
    9.     }
    10.  
    11.     *lpData = 0;
    12.  
    13.     __asm {
    14.         mov eax, [esp]
    15.         mov fs:[0], eax
    16.         add esp, 8
    17.     }
    18. ...
    Так вот, после загрузки DLL попадаю на int3. Оттуда прохожу под отладчиком установку SEH-обработчика handler. Но при выполнении *lpData = 0 выскакивает сообщение: "Unhandled exception at 0x005a1066 in dll-loader.exe: 0xC0000005: Access violation writing location 0x00000000."

    Уже всю голову себе сломал, почему не иксепшн обрабатывается... Кто знает, подскажите пожалуйста в чём дело может быть?...

    Спасибо.
     
  2. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Забыл ещё вот что сказать. Если вместо 'push offset handler' поместить 'push 0deadc0deh', то получается вот это: "Unhandled exception at 0xdeadc0de in dll-loader.exe: 0xC0000005: Access violation."
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    и это всё?

    Код (Text):
    1.     push offset SEH_proc    ; Адрес обработчика SEH
    2.     push fs:[0]     ; Адрес предидущего обработчика SEH
    3.     mov fs:[0], esp ; Установить свой SEH
    4.     ...
    5.  
    6. ;========================= Обработчик SEH ==================================
    7. SEH_proc proc C uses ebx edi esi, pExcept: dword, pFrame: dword, pContext: dword, pDispatch: dword
    8.     ...
    9.     mov eax, ExceptionContinueExecution ; Флаг продолжить выполнение программы
    10.   ret
    11. SEH_proc endp
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    сохранение регистров ebx edi esi в обработчике seh обязательно
     
  5. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Код (Text):
    1. DWORD handler(DWORD, DWORD, DWORD, DWORD)
    2. {
    3.     lpData = (LPDWORD)&lpData;
    4.  
    5.     return ExceptionContinueExecution;
    6. }
    Как-то без изменений... Я так думаю, что дело не в обработчике. Проверял до этого.
     
  6. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Кстати, набросал обработку точно такого же случая на masm32 - всё работает. Причём, в handler такой же простенький, как у меня был. Тут что-то именно с DLL и с MSVC....
     
  7. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Да, забыл вот ещё что отметить - загрузка DLL происходит без использования LoadLibrary. Как обычно разбирается заголовок, выделяется память, переносятся и настраиваются секции, импорты и т.д. Затем, вызывается DllMain. Может быть это ключ к ответу?..
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    А в дизасме это смотрел?
    С компилятор вообще-то может использовать для возврата не только eax, а любой понравившийся ему регистр.
     
  9. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    __stdcall по дефолту, думаю что eax используется для результата. Посмотрю :)
     
  10. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    По-моему так надо(в этой сказке против правил кто-то строчки переставил):
    Код (Text):
    1.     push fs:[0]     ; Адрес предыдущего обработчика SEH
    2.     push offset SEH_proc    ; Адрес обработчика SEH
    3.     mov fs:[0], esp ; Установить свой SEH
     
  11. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Если даже и так, то мне не помогло :dntknw:
     
  12. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    gorodon
    нет с порядок push не верный у тебя. Мой пример на asm выше полностью рабочий

    7mm
    Действительно странно
    Код (Text):
    1. LPDWORD lpData = NULL;
    2. DWORD handler() {
    3.     *lpData = (DWORD)&lpData;
    4.     return ExceptionContinueExecution;
    5. }
    6. // Начало основной программы
    7. void myMain(void)
    8. {
    9. //  __asm { int 3 }
    10.     __asm {
    11.         push offset handler
    12.         push fs:[0]
    13.         mov fs:[0], esp
    14.     }
    15.  
    16.     *lpData = 0;
    17.  
    18.     __asm {
    19.         mov eax, [esp]
    20.         mov fs:[0], eax
    21.         add esp, 8
    22.     }
    Компилится в
    Код (Text):
    1. 00401000   . A1 64304000    MOV EAX,DWORD PTR DS:[403064]            ;  Structured exception handler
    2. 00401005   . C700 64304000  MOV DWORD PTR DS:[EAX],Small_W3.00403064
    3. 0040100B   . 33C0           XOR EAX,EAX
    4. 0040100D   . C3             RETN
    5. 0040100E     CC             INT3
    6. 0040100F     CC             INT3
    7. 00401010 >/$ 56             PUSH ESI           ; <-- точка входа  программу
    8. 00401011  |. 68 00104000    PUSH Small_W3.00401000                   ;  SE handler installation
    9. 00401016  |. 64:FF35 000000>PUSH DWORD PTR FS:[0]
    10. 0040101D  |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
    11. 00401024  |. A1 64304000    MOV EAX,DWORD PTR DS:[403064]
    12. 00401029  |. C700 00000000  MOV DWORD PTR DS:[EAX],0
    13. 0040102F  |. 8B0424         MOV EAX,DWORD PTR SS:[ESP]
    14. 00401032  |. 64:A3 00000000 MOV DWORD PTR FS:[0],EAX
    15. 00401038  |. 83C4 08        ADD ESP,8
    т.е. обработчик SEH нормальный и оля распознаёт его установку но при установке бряка на 00401000 после исключения и Ctr F9 в этот бряк не попадаем, как будто и нет никакого сеха... Странно.

    ----
    Кстати заметь если с этим удастся разобраться возникнет другая заморочка:
    *lpData = 0;
    превращается в
    00401024 |. A1 64304000 MOV EAX,DWORD PTR DS:[403064]
    00401029 |. C700 00000000 MOV DWORD PTR DS:[EAX],0
    соответсвенно исключение происходит на второй строке этого кода, т.е. в обработчике нужно исправлять pContext.regEax, а для этого нужно быть уверенным что компилятор здесь использует именно eax :))
     
  13. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Кстати я пробовал безо всяких dll и спецзагрузчиков - обычный безCRTшный проект
     
  14. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Я пробую без CRT вообще (/NODEFAULTLIB) - всё та же хрень :dntknw:
     
  15. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    7mm
    я не про это - у меня тоже (/NODEFAULTLIB), а про:
    т.е. ключ к ответу точно не здесь.

    И главное как я показал выше самостотельная реализация SEH под C не столь тривиальна как кажется на первый взгляд (ты исправляешь переменную, а нужно исправлять регистр, да ещё угадать какой :). Поэтому вопрос ребром - а стоит ли овчинка выделки?
    Может лучше такие вещи целиком на асме или на родном для С цртшном SEH механизме делать? вместо такой труднопредсказуемой гремучей смеси.
     
  16. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    Мне не нужна CRTL так же как не нужна полноценная обработка исключений, достаточно того, чтобы они просто ловились через __try // __except , __try // __finally.
     
  17. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    а еще можно заинклудить exsup.lib в проект и юзать виндовый SEH от разработчика
    при /NODEFAULTLIB
     
  18. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    IMAGE_DLLCHARACTERISTICS_NO_SEH ?
     
  19. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    446
    0x0000
     
  20. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Может в этом и дело - попробуйте загрузку через LoadLibrary...так хотябы сузится круг поиска...