Обработка исключений в hook dll

Тема в разделе "WASM.WIN32", создана пользователем David, 10 янв 2007.

  1. David

    David New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    2
    Предыстория:
    есть приложение, которое устанавливает глобальный хук для всех процессов с помощью SetWindowsHookEx, естественно с использованием dll, которая по сути внедряется в каждый процесс в системе. Все работает нормально, но:

    вставляем следующий код на инициалицацию хук dll (delphi):
    try
    asm
    int 3
    end;
    except
    end;

    запускаем приложение... появляются ошибки в explorer.exe или ctfmon.exe. Ошибки типа "Программа обратилась к участку памяти ХХХХХХХХ"... система вешается...

    такие же ошибки возникают если в хук dll попытаться установить исключение через DRx регистры, и обработать его...

    В чем же здесь проблема? Почему нельзя использовать, допустим, Int 3 с обработчиком в этой библиотеке?

    Все эти приемы работают нормально в исполняемом exe файле, но не работают в хук dll...? Есть ли какие пути решения...
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    попробуй вручную через asm вставку
    Код (Text):
    1. program SEH;
    2. uses
    3.   Windows;
    4. type
    5.   _SEH = record
    6.     SafeEip:DWORD;     // The offset where it's safe to continue execution
    7.     PrevEsp:DWORD;     // The previous value of esp
    8.     PrevEbp:DWORD;     // The previous value of ebp
    9.   end;
    10.  
    11. //
    12. // Exception disposition return values.
    13. //
    14. EXCEPTION_DISPOSITION         =  DWORD;
    15. const
    16.   ExceptionContinueExecution  =  0;
    17.   ExceptionContinueSearch     =  1;
    18.   ExceptionNestedException    =  2;
    19.   ExceptionCollidedUnwind     =  3;
    20.  
    21.   szCaption     : PChar = 'SEH Test' + #0;
    22.   szNotOccured  : PChar = 'Exception NOT occured !' + #0;
    23.   szOccured     : PChar = 'Exception occured !' + #0;
    24. var
    25. __seh           : _SEH;
    26. lpText          : PAnsiChar;
    27. label   _SafePlace;
    28.  
    29.  
    30. {$O+}
    31. function _except_handler(
    32.     ExceptionRecord:PExceptionRecord;
    33.     EstablisherFrame:Pointer;
    34.     ContextRecord:PContext;
    35.     DispatcherContext:Pointer): EXCEPTION_DISPOSITION; cdecl;
    36. begin
    37.   ContextRecord.Eip := __seh.SafeEip;
    38.   ContextRecord.Esp := __seh.PrevEsp;
    39.   ContextRecord.Ebp := __seh.PrevEbp;
    40.   // Tell the OS to restart the faulting instruction
    41.   Result := ExceptionContinueExecution;
    42. end;
    43.  
    44.  
    45. {$O-}
    46. begin
    47.  lpText := szOccured;
    48.  asm
    49.    push  OFFSET _except_handler
    50.    push  DWORD PTR fs:[0]                 // address of next ERR structure
    51.    mov   fs:[0], esp                      // give FS:[0] the ERR address just made
    52.  
    53.    mov   __seh.SafeEip, OFFSET _SafePlace
    54.    mov   __seh.PrevEsp, esp
    55.    mov   __seh.PrevEbp, ebp
    56.  end;
    57.  asm
    58.    db 0CCh
    59.  end;
    60.  lpText := szNotOccured;
    61. _SafePlace:
    62.  asm
    63.    pop   DWORD PTR fs:[0]                 // restore next ERR structure to FS:[0]
    64.    add   esp, 4                           // throw away rest of ERR structure
    65.  end;
    66.  MessageBox(0, lpText, szCaption, MB_OK or MB_ICONINFORMATION);
    67. end.
     
  3. tar4

    tar4 New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2006
    Сообщения:
    43
    Я нечто подобное пытался как реализовать на дельфи, а потом отказался в пользу асма. Я пришел к выводу, что структура try.. except не корректно работает в данном случае с Seh (возможно, я не точно выразился). Вообщем, с Seh лучше работать из асма или Си.
     
  4. David

    David New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    2
    Дык вот и дело то в чем, не важно каким образом обработчик устанавливаешь... все равно не работает... вот пример котрый использовал в dll для обнуления отладочных регистров, так же как и int 3 не работает... но работает в обычном win32 exe (все исключения проходят и обрабатываются правильно),

    Код (Text):
    1.  
    2. asm
    3.     push offset @1
    4.     push fs:[0]
    5.     mov fs:[0], esp
    6.     xor eax, eax
    7.     // обращение к участку памяти [0]
    8.     @DoAccessViol:
    9.     xor [eax], eax
    10.     @DoDr0:
    11.     DB 00
    12.     @DoDr1:
    13.     DB 00
    14.     @DoDr2:
    15.     DB 00
    16.     @DoDr3:
    17.     DB 00
    18.     @D:
    19.     DD 0
    20.     @CaseAddr:
    21.       DD offset @DoDr0
    22.       DD offset @DoDr1
    23.       DD offset @DoDr2
    24.       DD offset @DoDr3
    25.     @CaseJmp:
    26.       DD offset @Dr0
    27.       DD offset @Dr1
    28.       DD offset @Dr2
    29.       DD offset @Dr3
    30.     // обработчик исключений    
    31.     @1:
    32.     mov eax, [esp+$C]
    33.     mov ecx, [esp+$4]
    34.     cmp [ecx], STATUS_ACCESS_VIOLATION
    35.     jz @AccessViol
    36.     cmp [ecx], STATUS_SINGLE_STEP
    37.     jz @Singlestep
    38.     @Singlestep:
    39.     mov edx, [offset @D]
    40.     mov ecx, [ecx+$C]
    41.     cmp ecx, [offset @CaseAddr + edx*4]
    42.     jnz @Exit
    43.     jmp [offset @CaseJmp + edx*4]
    44.     @Dr0:
    45.     mov edx, offset @DoDr1
    46.     jmp @NextDrx
    47.     @Dr1:
    48.     mov edx, offset @DoDr2
    49.     jmp @NextDrx
    50.     @Dr2:
    51.     mov edx, offset @DoDr3
    52.     jmp @NextDrx
    53.     @Dr3:
    54.     // сбрасываем отладочные регистры
    55.     mov [eax+04], 0
    56.     mov [eax+08], 0
    57.     mov [eax+12], 0
    58.     mov [eax+16], 0
    59.     and [eax+20], $FFFF0FF0
    60.     and [eax+24], $DC00
    61.     mov edx, offset @UnHandle
    62.     @NextDrx:
    63.     mov [eax+$B8], edx
    64.     xor eax, eax
    65.     ret
    66.     // Обработка обращения к памяти
    67.     @AccessViol :
    68.     cmp [ecx+$C], offset @DoAccessViol
    69.     jnz @Exit
    70.     mov [eax+$B8], offset @DoDr0
    71.     // Устанавливаем Drx регистры
    72.     mov [eax+04], offset @DoDr0 // Dr0
    73.     mov [eax+08], offset @DoDr1 // Dr1
    74.     mov [eax+12], offset @DoDr2 // Dr2
    75.     mov [eax+16], offset @DoDr3 // Dr3
    76.     and [eax+20], $FFFF0FF0 // Dr7
    77.     mov [eax+24], $155 // Flags
    78.     xor eax, eax
    79.     ret
    80.     @UnHandle:
    81.     pop fs:[0]
    82.     add esp, 4
    83.   end;
    Код малость отредактирован, так что работать просто не будет, я использую код 100 % правильно работающий... Но... вот в хуках не работает...

    Причем как уже и писал, ошибки возникают только в explorer и ctfmon, тем более даже не на всех версиях винды, например, даже есть 2 компа, с установленными XP SP2, на одном компе этот код работает, на другом вылетает... В чем же таки проблема...?