Код (Text): NTSTATUS NewNtTerminateThread ( IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus ) { ULONG ProcessId; THREAD_BASIC_INFORMATION threadbuff; NtQueryInformationThread(ThreadHandle,0,&threadbuff,sizeof(threadbuff),0); ProcessId =threadbuff.ClientId.UniqueProcess; if (ProcessId==(HANDLE)1004) { return STATUS_ACCESS_DENIED; } else return TrueNtTerminateThread(ThreadHandle,ExitStatus); }; Не работает и хоть убейся, уже месяц не могу заставить проверять ИД процесса-владельца. Путаюсь в указателях, исправьте, пожалуйста.
Да, суть кода должна быть таковой:есть хендл потока, по нему нужно получить ИД процесса-владельца и, если он равен 1004, то не дать завершить. NTSTATUS NtQueryInformationThread( __in HANDLE ThreadHandle, __in THREADINFOCLASS ThreadInformationClass, __inout PVOID ThreadInformation, __in ULONG ThreadInformationLength, __out_opt PULONG ReturnLength ); typedef struct _THREAD_BASIC_INFORMATION { NTSTATUS ExitStatus; PVOID TebBaseAddress; CLIENT_ID ClientId; KAFFINITY AffinityMask; KPRIORITY Priority; KPRIORITY BasePriority; } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
n2 Код у тебя правильный, не хватает только проверки результата вызова NtQueryInformationThread() и явного указания класса ThreadBasicInformation (хотя это и не обязательно, ибо этот класс и так равен 0, просто так нехорошо писать). Ну и в конце-концов: сам перехватчик-то вызывается вообще, проверял? К слову, я бы не стал так делать, я бы вызвал ObReferenceObjectByHandle(), чтобы получить указатель ETHREAD, и затем вызвал бы PsGetThreadProcessId() непосредственно для получения ID процесса, - так оверхед меньше.
А как проверить-то? Начались проблемы:Page Fault in nonepaged area. Вылетает при установке больше трёх перехватов.. Код (Text): ULONG GetPid(HANDLE ProcessHandle) { PEPROCESS process = 0; ULONG pId; ULONG pIdOffset=0x084; ObReferenceObjectByHandle(ProcessHandle, 0, NULL, UserMode, &process, NULL); pId = *(PULONG)(((ULONG)process) + pIdOffset); ObDereferenceObject(process); return pId; }; //функция - обработчик перехватаv NTSTATUS NewNtTerminateThread ( IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus ) { ULONG ProcessId; THREAD_BASIC_INFORMATION threadbuff; NtQueryInformationThread(ThreadHandle,0,&threadbuff,sizeof(threadbuff),0); DbgPrint("TryingNtTerminateThread with pid"); __try { ProcessId =threadbuff.ClientId.UniqueProcess; } __except(EXCEPTION_EXECUTE_HANDLER) { return STATUS_INVALID_PARAMETER; }; if (ProcessId==(HANDLE)888) { return STATUS_ACCESS_DENIED; } else return TrueNtTerminateThread(ThreadHandle,ExitStatus); }; NTSTATUS NewNtOpenThread( __out PHANDLE ThreadHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __in PCLIENT_ID ClientId ) { ULONG ProcessId; __try { ProcessId = ClientId->UniqueProcess; } __except(EXCEPTION_EXECUTE_HANDLER) { return STATUS_INVALID_PARAMETER; }; if (ProcessId == (HANDLE)888) { return STATUS_ACCESS_DENIED; } else return TrueNtOpenThread(ThreadHandle,DesiredAccess,ObjectAttributes,ClientId); }; NTSTATUS NewNtWriteVirtualMemory ( IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL ) { if (GetPid(ProcessHandle)==(HANDLE)888) { return STATUS_ACCESS_DENIED; } else return TrueNtWriteVirtualMemory ( ProcessHandle, BaseAddress, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten); };
Что!? Ой, не доводи до греха. Бряк в отладчике или вывод туда же. Дамп выкладывай. Желательно с Kernel Memory. Код ужасный, просто слов нет.
ULONG GetPid(HANDLE ProcessHandle) { PEPROCESS process = 0; ULONG pId; ULONG pIdOffset=0x084; ObReferenceObjectByHandle(ProcessHandle, 0, NULL, UserMode, &process, NULL); pId = *(PULONG)(((ULONG)process) + pIdOffset); ObDereferenceObject(process); return pId; }; Это первая и сразу ужастная функция ... Почему бы не написать что то вроде Код (Text): NTSTATUS GetPid( IN HANDLE ProcessHandle, OUT PULONG lpPid) { NTSTATUS Status; PEPROCESS process = 0; const ULONG pIdOffset = 0x084; *lpPid = 0; Status = ObReferenceObjectByHandle(ProcessHandle, 0, NULL, KeGetPreviousMode(), &process, NULL) if ( NTSUCCESS( Status ) ) { *lpPid = *(PULONG)(((ULONG)process) + pIdOffset); ObDereferenceObject(process); } //DbgPrint value of Status return Status; };
А так? Код (Text): NTSTATUS NewNtTerminateThread ( IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus ) { int id; PETHREAD thread=0; ObReferenceObjectByHandle(ThreadHandle,0, *PsProcessType, KernelMode, (PVOID*)&thread, NULL); id=(int)PsGetThreadProcessId(thread); DbgPrint("TerminateThread"); DbgPrint(id); return TrueNtTerminateThread(ThreadHandle,ExitStatus); };
В этом коде ошибка почти в каждой строчке, надо так: Код (Text): NTSTATUS NewNtTerminateThread ( IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus) { ULONG uPid = 0; PETHREAD thread = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; // // Получаем адрес объекта-потока. Маску доступа // можно не указывать, т.к. иначе вызов может завершиться // неудачей при отсутствии требуемых прав у объекта. // status = ObReferenceObjectByHandle ( ThreadHandle, THREAD_QUERY_INFORMATION, *PsThreadType, KernelMode, (PVOID*) &thread, NULL); if (! NT_SUCCESS (status)) { // // Обработка ошибок. // } // // Получаем ID процесса для указанного потока. // uPid = (ULONG) PsGetThreadProcessId ( thread); // // Освобождаем объект потока ибо не нужен более. // ObDereferenceObject ( thread); // // Пишем ID процесса в отладочный вывод. // DbgPrint ( "MYDRV: TerminateThread() called, Process ID = %u\n", uPid); // // Вызов оригинальной функции или следующего обработчика в цепочке. // return TrueNtTerminateThread ( ThreadHandle, ExitStatus); }
Забыл, да. Код обновил. Вот почему я не люблю "бумажные" собеседования Здесь заметка: Ну это зависит от целей перехвата вообще. Если нужно эмулировать клиента, то лучше здесь указать ExGetPreviousMode(), а если на клиента пофиг и нужно во что бы то ни стало получить доступ к объекту, обойдя проверки доступа, то лучше KernelMode указывать.
x64, благодарю, сейчас попробую. И почему же в каждой строке ошибка? Да, я не проверял статус и т.д., ибо это уже не так важно, как сам факта рабочей функции.