Предыстория: есть приложение, которое устанавливает глобальный хук для всех процессов с помощью SetWindowsHookEx, естественно с использованием dll, которая по сути внедряется в каждый процесс в системе. Все работает нормально, но: вставляем следующий код на инициалицацию хук dll (delphi): try asm int 3 end; except end; запускаем приложение... появляются ошибки в explorer.exe или ctfmon.exe. Ошибки типа "Программа обратилась к участку памяти ХХХХХХХХ"... система вешается... такие же ошибки возникают если в хук dll попытаться установить исключение через DRx регистры, и обработать его... В чем же здесь проблема? Почему нельзя использовать, допустим, Int 3 с обработчиком в этой библиотеке? Все эти приемы работают нормально в исполняемом exe файле, но не работают в хук dll...? Есть ли какие пути решения...
попробуй вручную через asm вставку Код (Text): program SEH; uses Windows; type _SEH = record SafeEip:DWORD; // The offset where it's safe to continue execution PrevEsp:DWORD; // The previous value of esp PrevEbp:DWORD; // The previous value of ebp end; // // Exception disposition return values. // EXCEPTION_DISPOSITION = DWORD; const ExceptionContinueExecution = 0; ExceptionContinueSearch = 1; ExceptionNestedException = 2; ExceptionCollidedUnwind = 3; szCaption : PChar = 'SEH Test' + #0; szNotOccured : PChar = 'Exception NOT occured !' + #0; szOccured : PChar = 'Exception occured !' + #0; var __seh : _SEH; lpText : PAnsiChar; label _SafePlace; {$O+} function _except_handler( ExceptionRecord:PExceptionRecord; EstablisherFrame:Pointer; ContextRecord:PContext; DispatcherContext:Pointer): EXCEPTION_DISPOSITION; cdecl; begin ContextRecord.Eip := __seh.SafeEip; ContextRecord.Esp := __seh.PrevEsp; ContextRecord.Ebp := __seh.PrevEbp; // Tell the OS to restart the faulting instruction Result := ExceptionContinueExecution; end; {$O-} begin lpText := szOccured; asm push OFFSET _except_handler push DWORD PTR fs:[0] // address of next ERR structure mov fs:[0], esp // give FS:[0] the ERR address just made mov __seh.SafeEip, OFFSET _SafePlace mov __seh.PrevEsp, esp mov __seh.PrevEbp, ebp end; asm db 0CCh end; lpText := szNotOccured; _SafePlace: asm pop DWORD PTR fs:[0] // restore next ERR structure to FS:[0] add esp, 4 // throw away rest of ERR structure end; MessageBox(0, lpText, szCaption, MB_OK or MB_ICONINFORMATION); end.
Я нечто подобное пытался как реализовать на дельфи, а потом отказался в пользу асма. Я пришел к выводу, что структура try.. except не корректно работает в данном случае с Seh (возможно, я не точно выразился). Вообщем, с Seh лучше работать из асма или Си.
Дык вот и дело то в чем, не важно каким образом обработчик устанавливаешь... все равно не работает... вот пример котрый использовал в dll для обнуления отладочных регистров, так же как и int 3 не работает... но работает в обычном win32 exe (все исключения проходят и обрабатываются правильно), Код (Text): asm push offset @1 push fs:[0] mov fs:[0], esp xor eax, eax // обращение к участку памяти [0] @DoAccessViol: xor [eax], eax @DoDr0: DB 00 @DoDr1: DB 00 @DoDr2: DB 00 @DoDr3: DB 00 @D: DD 0 @CaseAddr: DD offset @DoDr0 DD offset @DoDr1 DD offset @DoDr2 DD offset @DoDr3 @CaseJmp: DD offset @Dr0 DD offset @Dr1 DD offset @Dr2 DD offset @Dr3 // обработчик исключений @1: mov eax, [esp+$C] mov ecx, [esp+$4] cmp [ecx], STATUS_ACCESS_VIOLATION jz @AccessViol cmp [ecx], STATUS_SINGLE_STEP jz @Singlestep @Singlestep: mov edx, [offset @D] mov ecx, [ecx+$C] cmp ecx, [offset @CaseAddr + edx*4] jnz @Exit jmp [offset @CaseJmp + edx*4] @Dr0: mov edx, offset @DoDr1 jmp @NextDrx @Dr1: mov edx, offset @DoDr2 jmp @NextDrx @Dr2: mov edx, offset @DoDr3 jmp @NextDrx @Dr3: // сбрасываем отладочные регистры mov [eax+04], 0 mov [eax+08], 0 mov [eax+12], 0 mov [eax+16], 0 and [eax+20], $FFFF0FF0 and [eax+24], $DC00 mov edx, offset @UnHandle @NextDrx: mov [eax+$B8], edx xor eax, eax ret // Обработка обращения к памяти @AccessViol : cmp [ecx+$C], offset @DoAccessViol jnz @Exit mov [eax+$B8], offset @DoDr0 // Устанавливаем Drx регистры mov [eax+04], offset @DoDr0 // Dr0 mov [eax+08], offset @DoDr1 // Dr1 mov [eax+12], offset @DoDr2 // Dr2 mov [eax+16], offset @DoDr3 // Dr3 and [eax+20], $FFFF0FF0 // Dr7 mov [eax+24], $155 // Flags xor eax, eax ret @UnHandle: pop fs:[0] add esp, 4 end; Код малость отредактирован, так что работать просто не будет, я использую код 100 % правильно работающий... Но... вот в хуках не работает... Причем как уже и писал, ошибки возникают только в explorer и ctfmon, тем более даже не на всех версиях винды, например, даже есть 2 компа, с установленными XP SP2, на одном компе этот код работает, на другом вылетает... В чем же таки проблема...?