Flasher Насчёт запрета обработки апк замечаний вроде как нет, только плохой это способ. Метод с исключениями универсален и весьма прост. Смещать диспетчер исключений не нужно - код который его перехватывает наверно умеет делоть цепочки хэндлеров, поставь его как фрейм, говорил уже что можно VEH заюзоть, если первое не получаетсо. Не пойму чем тебе не нравится этот способ :P, как по мне так самое то.
Flasher Вот код диспетчера, ставь как последний в цепочке VEH-фрейм: Код (Text): TEB_RETURN_FROM_SERVICE_OFFSET equ (PAGE_SIZE - 4*8) ;Думою коллизий не будет со смещением.. .code comment ' Перед вызовом сервиса необходимо загрузить адрес возврата из инструкции вызывающей сервис посредством Int2e в TEB по смещению TEB_RETURN_FROM_SERVICE_OFFSET. Атомарно это не нужно делоть, так как изменять каждый поток будет свой TEB. Диспетчер исключений должен сбрасывать флаг TF и возвращать управлние на текущую инструкцию если адрес её равен установленному в TEB. Иначе это попытка внедрения. Тоесть вызов сервиса выглядит как(для Sysenter не нужно загружать адрес): [...] push EFLAGS_TF Call delta_ delta_: add dword ptr [esp],(offset break_ - offset delta_) pop dword ptr fs:[TEB_RETURN_FROM_SERVICE_OFFSET] popfd int 2eh nop break_: [...]' ;Устанавливаем диспетчер как векторный обработчик исключений. VectoredHandler proc uses ebx ExceptionPointers:PEXCEPTION_POINTERS xor eax,eax mov ebx,ExceptionPointers assume ebx:PEXCEPTION_POINTERS mov edx,[ebx].ExceptionRecord assume edx:PEXCEPTION_RECORD cmp [edx].ExceptionFlags,eax ;Не фатальная ошибка. jne exit_ cmp [edx].ExceptionCode,STATUS_SINGLE_STEP jne exit_ ;Исключение вызвано по возврату из севрса. Для сервиса вызванного посредством прерывания это адрес ;следующей за Int2e инструкции, посредством инструкции Sysenter это адрес в UsSharedData поле SystemCallRet. ;Поэтому пропускаем SystemCallRet. assume fs:nothing mov eax,KUSER_SHARED_DATA_ADDRESS + KUSER_SHARED_DATA.SystemCallRet mov ecx,fs:[TEB_RETURN_FROM_SERVICE_OFFSET] cmp [edx].ExceptionAddress,eax ;Лучше былобы проверить версию системы, только для XPSP1 данная проверка. je return_ mov eax,dword ptr [eax] je return_ cmp [edx].ExceptionAddress,eax je return_ cmp [edx].ExceptionAddress,ecx je return_ ;Эта процедура проверяет является ли апк чужой, тоесть поставлено в очередь не из текущего процесса. ; invoke IsRemoteApc, [edx].ExceptionAddress ; test eax,eax ; jz return_ ;Обнаружено внедрение. К примеру прибиваем процесс. xor esp,esp push eax return_: ;Возвращаем управление на прерванную инструкцию, предварительно сбросив TF. mov edx,[ebx].ContextRecord assume edx:PCONTEXT xor eax,eax and [edx].regEFlags,Not EFLAGS_TF dec eax ;EXCEPTION_CONTINUE_EXECUTION exit_: ret VectoredHandler endp Остальное вроде всё гладко.. Кстати оптимизировал GetSystemService(избавилсо от надоевших импортов) :
Flasher Прошу прощенья, я затупил почемуто диспетчер, (вспомнил когда уже комп выключил). Ведь изза взведённого eflags.rf инструкция по адресу UsSystemCallRet вызовет исключение только после исполнения, тоесть диспетчер исключений получит его адрес равный значению на вершине стека, куда указывал регистр Edx перед вызовом сервиса(регистр Esp не имеет значения). Тоесть так: Код (Text): VectoredHandler proc uses ebx ExceptionPointers:PEXCEPTION_POINTERS xor eax,eax mov ebx,ExceptionPointers assume ebx:PEXCEPTION_POINTERS mov edx,[ebx].ExceptionRecord assume edx:PEXCEPTION_RECORD cmp [edx].ExceptionFlags,eax jne exit_ cmp [edx].ExceptionCode,STATUS_SINGLE_STEP jne exit_ assume fs:nothing mov eax,fs:[TEB_RETURN_FROM_SERVICE_OFFSET] cmp [edx].ExceptionAddress,eax je return_ ; invoke IsRemoteApc, [edx].ExceptionAddress ; test eax,eax ; jz return_ xor esp,esp push eax return_: mov edx,[ebx].ContextRecord assume edx:PCONTEXT xor eax,eax and [edx].regEFlags,Not EFLAGS_TF dec eax ;EXCEPTION_CONTINUE_EXECUTION exit_: ret VectoredHandler endp Для Int2e модель вызова таже, для Sysenter соответственно такая: Код (Text): [...] push EFLAGS_TF push dword ptr [edx] pop dword ptr fs:[TEB_RETURN_FROM_SERVICE_OFFSET] popfd sysenter Вроде всё правильно(я совсем сдурел ппц..).
Ловлю KiUserExceptionDispatcher через InstallExceptionDispatcher и указываю на обработчик VectoredHandler. Ловлю KiFastSystemCall через SplaysKiFastSystemCall и указываю на обработчик Код (Text): KiFastSystemCallHandler: assume fs:nothing push EFLAGS_TF Call delta_ delta_: add dword ptr [esp],(offset break_ - offset delta_) pop dword ptr fs:[TEB_RETURN_FROM_SERVICE_OFFSET] popfd lea edx,dword ptr [esp+8] int 2Eh break_: ret Так ?
Если InstallExceptionDispatcher() то диспетчера модель вызова другая, там есчо пользовательский параметр есть. Второе верно.