Прочитал статью «Перехват API функций в Windows NT (часть 3). Нулевое кольцо.» Собственно драйвер NoTerminate работает через раз, файл NoTerminate.exe можно закрыть без всяких проблем, тем же TaskManager’ом. В чем дело и есть ли какой-нибудь более простой поиск PID в перехватчике, нежели чем через структуру CLIENT_ID. В аттаче два исходника один Ms-Rem на С, другой мой на ASM.
Код (Text): NTSTATUS MyZwTerminateProcess(IN HANDLE ProcessHandle, IN NTSTATUS ExitStatus) { PVOID pObject = NULL; POBJECT_HANDLE_INFORMATION HandleInformaton = NULL; UNICODE_STRING fNameU; // процесс пытается заглушить сам себя без санкции либо кто-то выпалил наш хэндл if (ProcessHandle == 0) { if ((ProcessIdToHide == PsGetCurrentProcessId()) && (SetHideProcess)) return STATUS_ACCESS_DENIED; } // найдём процесс по хэндлу и проверим if (NT_SUCCESS(ObReferenceObjectByHandle(ProcessHandle,FILE_ANY_ACCESS,NULL,KernelMode,&pObject,NULL))) { ObDereferenceObject(pObject); // ссылка нам больше не нужна мы получили &EPROCESS RtlInitUnicodeString(&fNameU,L"PsGetProcessId"); if ((ProcessIdToHide == ((PVOID)((NTPROC)MmGetSystemRoutineAddress(&fNameU))(pObject))) && (SetHideProcess)) return STATUS_ACCESS_DENIED; } return TrueZwTerminateProcess(ProcessHandle, ExitStatus); }
Понял в чем дело, выложенные мною исходники работают,TaskManadger не может завершить процесс (что и требовалось), но может завершить задачу. k3internal Plz выложи исходник драйвера перехвата ZwTerminateProcess, а то по приведенному куску кода мало, что понятно. И еще вопрос почему ты производишь перехват функции ZwTerminateProcess, а не NtTerminateProcess?
>> Plz выложи исходник драйвера перехвата ZwTerminateProcess, а то по приведенному куску кода мало, что понятно. дык что конкретно здесь непонятного, я думаю здсть кроме обработчка хукнутой ф-ции (который собсно и был выложен) и не нужно ничего)
Точка входа у этих функций одна, так что принципиальной разницы нет Еще раз внимательно пречитай Рэма. Его статьи рулят. А поиск PID - куда уж проще?? Тут уже я не понял. Т.е. приложение получает сообщение, что нужно завершиться, и далее начинает процедуру завершения, которая по идее сводится к ExitProcess----->ZwTerminateProcess Как в таком случае завершается задача???
nitrotoluol <Точка входа у этих функций одна, так что принципиальной разницы нет > Нет. Точки входа у них разные. Смотри внимательнее. Denis__ <Plz выложи исходник драйвера перехвата ZwTerminateProcess, а то по приведенному куску кода мало, что понятно. И еще вопрос почему ты производишь перехват функции ZwTerminateProcess, а не NtTerminateProcess?> Драйвер страшный. Ты спроси что тебе непонятно. Объясню.
k3internal Каким образом до обработчика MyZwTerminateProcess получем ProcessIdToHide, SetHideProcess - что это ?
Сыграю роль телепата SetHideProcess из контекста мне кажется, что это флаг показывающий надо ли запрещать завершение какого-то процесса(флаг может устанавливаться через ioctl например). ProcessIdToHide можно получить например при вызове того же ioctl. PsGetCurrentProcess, получили PEPROCESS, берём оттуда хендл, ну или поставили NotifyRoutine, и если запустился процесс который нужно защитить, то также получаем его пид.
На счет SetHideProcess, хотелось бы по конкретней желательно с примерчиком. Просто не до конца логику пойму, зачем нам какой-то флаг, у нас же есть PID, который получаем через ioctl.
ProcessIdToHide это Id подконтрольного процесса. SetHideProcess это просто булевая переменная, показывающая, нужно запретить уничтожение процесса или хрен с ним.
Добрый вечер. Перехватываю NtTerminateProcess,ниже код обработчика. Код (Text): NewNtTerminateProcess proc ProcessHandle:dword,ExitStatus:dword local pEPROCESS:dword local ProcessId:dword invoke ObReferenceObjectByHandle,ProcessHandle, 0, NULL, KernelMode, addr pEPROCESS, NULL .if eax==STATUS_SUCCESS mov eax,[pEPROCESS] mov ecx,[PidOffset] mov eax,[eax+ecx] ;PID процесса mov ProcessId,eax invoke DbgPrint, $CTA0("Protected process %d terminated"),ProcessId invoke ObDereferenceObject,pEPROCESS invoke IsAdded,wLastItem, ProcessId ;проверяем есть ли в списке защищеных процесов данный PID .if eax!=0 invoke DbgPrint, $CTA0("Access Denied") ;запрещаем доступ mov eax,STATUS_ACCESS_DENIED ret .endif .endif push ExitStatus ;вызываем оригинальный обработчик push ProcessHandle call TrueNtTerminateProcess ret NewNtTerminateProcess endp Код почти рабочий . Все работает,недаем убить защищенные процессы,незащищенные отправляем на оригинальный обработчик NtTerminateProcess.Но как только происходит вызов оригинального обработчика NtTerminateProcess,закрываемый процесс зависает.То же самое происходит,если попытаться просто закрыть процесс, то есть нажать на крестик или ALT+F4.Не пойму где ошибка, в отладчике ее явно не видно
Нашел ошибку, нажно еще проверять,вдруг мы закрываем сами себя. Ниже рабочий код: Код (Text): NewNtTerminateProcess proc ProcessHandle:dword,ExitStatus:dword local pEPROCESS:dword local ProcessId:dword invoke PsGetCurrentProcessId invoke IsAdded,wLastItem, eax ;В eax PID процесса, если PID= PID какого то из наших,защищенных процессов,значит пытаемся закрыть сами себя .if eax==0 ;прыгаем на оригинальный обработчик NtTerminateProcess invoke ObReferenceObjectByHandle,ProcessHandle, 0, NULL, KernelMode, addr pEPROCESS, NULL .if eax==STATUS_SUCCESS mov eax,[pEPROCESS] mov ecx,[PidOffset] mov eax,[eax+ecx] mov ProcessId,eax invoke ObDereferenceObject,pEPROCESS invoke IsAdded,wLastItem, ProcessId .if eax!=0 invoke DbgPrint, $CTA0("Access Denied") mov eax,STATUS_ACCESS_DENIED ret .endif .endif .endif push ExitStatus push ProcessHandle call TrueNtTerminateProcess ret NewNtTerminateProcess endp